Mykeul
Mykeul

Reputation: 558

Load data to Ehcache 3 on Spring Boot start up

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

Answers (1)

Mykeul
Mykeul

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

Related Questions