26

On app start, I initialized ~20 different caches:

@Bean
public CacheManager cacheManager() {
    SimpleCacheManager cacheManager = new SimpleCacheManager();
    cacheManager.setCaches(Arrays.asList(many many names));
    return cacheManager;
}

I want to reset all the cache at an interval, say every hr. Using a scheduled task:

@Component
public class ClearCacheTask {

    private static final Logger logger = LoggerFactory.getLogger(ClearCacheTask.class);
    private static final DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd hh:mm:ss");

    @Value("${clear.all.cache.flag}")
    private String clearAllCache;

    private CacheManager cacheManager;

    @CacheEvict(allEntries = true, value="...............")
    @Scheduled(fixedRate = 3600000, initialDelay = 3600000) // reset cache every hr, with delay of 1hr
    public void reportCurrentTime() {
        if (Boolean.valueOf(clearAllCache)) {
            logger.info("Clearing all cache, time: " + formatter.print(DateTime.now()));
        }
    }
}

Unless I'm reading the docs wrong, but @CacheEvict requires me to actually supply the name of the cache which can get messy.

How can I use @CacheEvict to clear ALL caches?

I was thinking instead of using @CacheEvict, I just loop through all the caches:

cacheManager.getCacheNames().parallelStream().forEach(name -> cacheManager.getCache(name).clear());
3
  • 3
    Instead of hacking something together why not use a proper cache implementation like ehcache which supports this by simply configuring the cache.
    – M. Deinum
    Commented Jul 13, 2016 at 18:57
  • i should have add the disclaimer: yes, this is stupid/hacky but it has to be done. Commented Jul 14, 2016 at 19:29
  • I would go for option 2, don't try to use @CacheEvict for that as it wasn't designed for that, but still it is a hack and you should probably use a proper caching technology instead.
    – M. Deinum
    Commented Jul 15, 2016 at 5:45

2 Answers 2

67

I just used a scheduled task to clear all cache using the cache manager.

@Component
public class ClearCacheTask {
    @Autowired
    private CacheManager cacheManager;

    @Scheduled(fixedRateString = "${clear.all.cache.fixed.rate}", initialDelayString = "${clear.all.cache.init.delay}") // reset cache every hr, with delay of 1hr after app start
    public void reportCurrentTime() {
        cacheManager.getCacheNames().parallelStream().forEach(name -> cacheManager.getCache(name).clear());
    }
}

Gets the job done.

1
  • 5
    For all new to scheduling with spring boot: don't forget to add the @EnableScheduling annotation to your spring boot application class. (Where you already should have the @SpringBootApplication and the @EnableCaching annotations.)
    – Datz
    Commented May 14, 2019 at 6:29
3

Below evictCache method evicts fooCache using @CacheEvict annotation.

public class FooService {

  @Autowired 
  private FooRespository repository;

  @Cacheable("fooCache")
  public List<Foo> findAll() {
    return repository.findAll();
  }

  @CacheEvict(value="fooCache",allEntries=true)
  public void evictCache() {
    LogUtil.log("Evicting all entries from fooCache.");
  }
}
2
  • But when would that been executed? Do you need to schedule it or something, right? Commented Sep 18, 2020 at 13:44
  • That's exactly opposite to what OP asked for. If there are 20 other types of caches apart from fooCache, @CacheEvict cannot be used.
    – saran3h
    Commented Sep 26, 2020 at 8:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.