I'm having the issue when my cache keys are colliding in Spring using the @Cacheable
annotation. For instance, with the following two methods:
@Cacheable("doOneThing")
public void doOneThing(String name) {
// do something with name
}
@Cacheable("doAnotherThing")
public void doAnotherThing(String name) {
// do some other thing with name
}
Here is my cache configuration, in which I've added a keyGenerator
and a cacheManager
bean:
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public JedisConnectionFactory redisConnectionFactory() {
return new JedisConnectionFactory();
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
redisTemplate.setConnectionFactory(cf);
return redisTemplate;
}
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
return new RedisCacheManager(redisTemplate);
}
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(o.getClass().getName());
sb.append(method.getName());
for (Object param : params) {
sb.append(param.toString());
}
return sb.toString();
}
};
}
}
For some reason, the cache key always gets set to the name
parameter in the method, not the result of the keyGenerator.generate(..)
method, causing both methods to return the same cache result.
I know that I can specify the key manually on each @Cacheable
annotation, but that seems a little extensive for every method I'd like to cache.
I've noticed that setting the keyGenerator
option inside of the @Cacheable
annotation to the name of my bean resolves the issue, like so:
@Cacheable(value = "doOneThing", keyGenerator = "keyGenerator")
public void doOneThing(String name) {
// do something with name
}
And setting the keyGenerator
option in the @CacheConfig
annotation on the class also resolves the issue. It seems that this shouldn't be necessary though. Am I missing something?
Your configuration should implement CachingConfigurer
(usually you would extend from CachingConfigurerSupport
) to customize how caching works.