Clear Redis Cache on Spring Boot Application Startup
Asked Answered
S

3

6

On application (spring boot service) startup, need to clear the Redis cache.

Redis is running in a different docker container with own volume mapping. Since it retains the old cache, the application picks the data from Redis cache instead of Database even after the application restarts

  • Tried @EventListener for ContextRefreshedEvent and it is never getting called.
  • Tried with @PostConstruct in ApplicationMain class, but it doesn't clear the cache.
  • Tried using @CacheEvict(allEntries = true), but still no luck

    @Component public class ApplicationStartUp {

    @Autowired
    private CacheManager cacheManager;
    
    @EventListener()
    public void onApplicationEvent(ContextStartedEvent event) {
        cacheManager.getCacheNames()
                    .parallelStream()
                    .forEach(n -> cacheManager.getCache(n).clear());
    }
    

    }

Suited answered 5/1, 2020 at 18:11 Comment(2)
Have you verified onApplicationEvent is actually being triggered and you are able to get cache values in loop. ?Salado
Do you see your cache name, if you print the result of cacheManager.getCacheNames()? It's possible the cache manager doesn't return any, on start up. As a test, try using @PostConstruct and cacheManger.getCache("your cache").clear().Kosiur
S
7

I was successfully able to clear the cache with ApplicationReadyEvent. As the CacheManager bean is available by the time, the cache is getting cleared properly on startup

@Autowired
private CacheManager cacheManager;

@EventListener
public void onApplicationEvent(ApplicationReadyEvent event) {
    cacheManager.getCacheNames()
                .parallelStream()
                .forEach(n -> cacheManager.getCache(n).clear());
}
Suited answered 6/1, 2020 at 18:36 Comment(3)
Could you please provide me you cacheconfig class. I am implementing something similar to this and still facing some issue.Sieber
Are you getting all cached data, because cacheManager.getCacheNames() doesn't return cached data. How you are getting?Nevins
@senthil cacheManager.getCacheNames() returning empty data. How did this work for you ? I have same codeOctofoil
D
4

A simple practice to clear Redis DB at earlier life cycle stage. To config CacheManager @bean with argument RedisConnectionFactory passed in, calling flushDb() to delete all keys of the currently selected database before build up.

 @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        redisConnectionFactory.getConnection().flushDb(); //Delete all keys of the currently selected database
        return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory)).cacheDefaults(RedisCacheConfiguration.defaultCacheConfig()).build();
    }
Danseuse answered 4/1, 2023 at 9:43 Comment(0)
K
2

For the Redis cache manager, if you want to clear the cache on boot, I think you will need to initialize the cache manager with a set of names. See the RedisCacheManagerBuilder docs

For example:

RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory)
                        .initialCacheNames(Set.of("cacheOne", "cacheTwo"))
                        .build();

Then you should be able to use @PostConstruct in you cache config class, for example.

@PostConstruct
public void clearCache() {
    cacheManager.getCacheNames()
                .parallelStream()
                .forEach(n -> cacheManager.getCache(n).clear());
}
Kosiur answered 6/1, 2020 at 8:2 Comment(3)
Thanks for the suggestion. But I changed ContextRefreshedEvent listener to ApplicationReadyEvent listener, it worked properlySuited
@Suited Cool, thanks for posting your solution as well.Kosiur
Without initializing cache names is it possible to clear the cache?Nevins

© 2022 - 2024 — McMap. All rights reserved.