Reputation: 558
I would like to load data in cache when my Spring Boot application starts. I know there is an integrated way using BootstrapCacheLoader in Ehcache2. How to load data from database to Ehcache when the application starts But I don't see this in Ehcache3. I still can do it manually within a @postConstruct method. But I was wondering if there is an integrating solution (Spring 5, Ehcache 3)
Thank you.
Upvotes: 1
Views: 1255
Reputation: 558
I've ended up doing it after the Spring context has been initialized. For each element in the DB collection, I call getResourceById() which has the @Cacheable annotation, thus populating the cache for the whole DB collection.
I don't recommend to run this code in a @PostConstruct as proxies may not have been created yet and annotations like @Cacheable may not be working yet.
Running this code when a ContextRefreshedEvent event is triggered (after initialization or after refresh) is a more appropriate place to load the cache.
public class CacheLoader {
private final Logger logger = LoggerFactory.getLogger(CacheLoader.class);
@Autowired
private ResourcePermissionRepository resourcePermissionRepository;
@Autowired
private ResourcePermissionService resourcePermissionService;
@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
logger.info("Loading cache following start/refresh event");
for (PermissionGroup permissionGroup : permissionGroupRepository.findAll()) {
permissionGroupService.getGroupById(permissionGroup.getGroupName());
}
for(ResourcePermission resourcePermission: resourcePermissionRepository.findAll()) {
resourcePermissionService.getResourceById(resourcePermission.getResourceId());
}
logger.info("Finished loading cache");
}
public class ResourcePermissionService {
private final Logger logger = LoggerFactory.getLogger(ResourcePermissionService.class);
@Autowired
private ResourcePermissionRepository resourcePermissionRepository;
@Cacheable(value = "resources", sync = true)
public ResourcePermission getResourceById(String resourceId) {
logger.info("Cache miss for resource " + resourceId);
return resourcePermissionRepository.findById(resourceId).orElse(new NullResourcePermission());
}
@CachePut(value = "resources", key = "#result.resourceId")
public ResourcePermission addResourcePermission(ResourcePermission resourcePermission) {
return resourcePermissionRepository.save(resourcePermission);
}
@CacheEvict(value = "resources")
public void deleteById(String resourceId) {
resourcePermissionRepository.deleteById(resourceId);
}
}
Upvotes: 1