Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reload/Refresh cache in spring boot

I am using Spring Boot and for caching I am using Ehcache. It's working fine till now. But now I have to reload / refresh so how can I do this so that my application will not be having any downtime.

I have tried many ways in Spring Ehcache but it didn't work or Else have to write a scheduler and reload the data.

@Override
@Cacheable(value="partTypeCache", key="#partKey")
public List<PartType> loadPartType(String partKey) throws CustomException {
        return productIdentityDao.loadPartType();
}
like image 564
Shubuu Avatar asked Jun 05 '19 10:06

Shubuu


3 Answers

Apparently all the comments about your problem were right. You should use CacheEvict. I found solution here: https://www.baeldung.com/spring-boot-evict-cache and it looks like this:

All you have to do is create class called e.g. CacheService and create method that will evict all cached objects you have. Then you annotate that method @Scheduled and put your interval rate.

@Service
public class CacheService {

    @Autowired
    CacheManager cacheManager;

    public void evictAllCaches() {
        cacheManager.getCacheNames().stream()
          .forEach(cacheName -> cacheManager.getCache(cacheName).clear());
    }

    @Scheduled(fixedRate = 6000)
    public void evictAllcachesAtIntervals() {
        evictAllCaches();
    }

}
like image 96
J.Kennsy Avatar answered Oct 06 '22 19:10

J.Kennsy


The option suggested by many to use @CacheEvict is correct. Additionally, to ensure your cache (near) always has latest data loaded, even if data is updated in database out of bounds to your running app, you need to reload the whole dataset periodically with an interval matching your app's SLAs. In the solution suggested above, add logic to reload all data like below:

@Service
public class CacheService {

    @Autowired
    CacheManager cacheManager;

    public void refreshAllCaches() {
        cacheManager.getCacheNames().stream()
          .forEach(cacheName -> cacheManager.getCache(cacheName).clear());
        // reload whole dataset here, dummy example here:
        dataRepository.findAll().forEach(a -> cacheManager.getCache("cache-name")).put(a.getKey(), a));
    }

    @Scheduled(fixedRate = 6000)
    public void refreshAllcachesAtIntervals() {
        refreshAllCaches();
    }

}
like image 42
V_Singh Avatar answered Oct 06 '22 20:10

V_Singh


Try something like this, as mentioned in comments also:

    @Caching(evict={@CacheEvict(value="partTypeCache", key="#partKey")})
    public boolean deletePartType(String partKey) { 
      //when this method is invoked the cache is evicted for the requested key
    }
like image 24
TechFree Avatar answered Oct 06 '22 18:10

TechFree