I am searching a way to set the TTL with spring annotation.
I tried
@CacheEvict(allEntries = true, value = { "mycache" })
@Scheduled(fixedDelay = 5000)
And putting @EnableScheduling
on my Application.java
with no success.
I also tried @RedisHash(timeToLive=2000)
on the class with and without @TimeToLive(unit = TimeUnit.SECONDS)
on method.
Then I tried to put @EnableRedisRepositories(keyspaceConfiguration = UserKeySpaceConfiguration.class)
on my class
public class UserKeySpaceConfiguration extends KeyspaceConfiguration {
/**
* {@inheritDoc}
*
* @see org.springframework.data.redis.core.convert.KeyspaceConfiguration#getKeyspaceSettings(java.lang.Class)
*/
@Override
public KeyspaceSettings getKeyspaceSettings(final Class<?> type) {
final KeyspaceSettings keyspaceSettings = new KeyspaceSettings(type, "user-keyspace");
keyspaceSettings.setTimeToLive(172800L);
return keyspaceSettings;
}
/**
* {@inheritDoc}
* @see org.springframework.data.redis.core.convert.KeyspaceConfiguration#hasSettingsFor(java.lang.Class)
*/
@Override
public boolean hasSettingsFor(final Class<?> type) {
return true;
}
}
All this method don't work.
When I check Redis if my keys have TTL, I always have -1
.
Any idea on how to proceed ?
Thanks.
Well after a week of search I found a solution.
To have different TTL on different keys you have to create your own cache manager.
So in your Application.java
add your custom cache manager.
@SpringBootApplication
@EnableSwagger2
@EnableCaching
public class Application extends SpringBootServletInitializer {
public static void main(final String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
@Primary
@Bean
public RedisCacheManager cacheManager(final RedisConnectionFactory connectionFactory) {
final RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
final SerializationPair<Object> valueSerializationPair = RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer());
final RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
final RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter, cacheConfiguration);
return redisCacheManager;
}
@Bean(name = "pickleCacheManager")
public RedisCacheManager pickleCacheManager(final RedisConnectionFactory connectionFactory) {
final RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
final SerializationPair<Object> valueSerializationPair = RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer());
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
cacheConfiguration = cacheConfiguration.entryTtl(Duration.ofSeconds(120));
final RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter, cacheConfiguration);
return redisCacheManager;
}
@Bean(name = "userCacheManager")
public RedisCacheManager userCacheManager(final RedisConnectionFactory connectionFactory) {
final RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
final SerializationPair<Object> valueSerializationPair = RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer());
RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
cacheConfiguration = cacheConfiguration.entryTtl(Duration.ofSeconds(172800));
final RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter, cacheConfiguration);
return redisCacheManager;
}
}
To make the difference between your cache, you have the attribut name
with annotation @Bean
.
You need to have a @Primary
@Bean
or your application will crash. In my case my primary juste return the cache without change.
So in this custom cache I just add a TTL with
cacheConfiguration = cacheConfiguration.entryTtl(Duration.ofSeconds(120));
And when you use your cache on a method you just need to specify your cache like so:
@Cacheable(value = "value", key = "#key", cacheManager = "yourCacheName")
In my case
@Cacheable(value = "pickle", key = "#pickleId", cacheManager = "pickleCacheManager")
Pickle findFirstById(String pickleId);
Your cacheManager
in @Cacheable
is your name
in @Bean
.