I am using Spring Boot 3.x with Redis and Redisson as a second-level cache. Everything works as expected while the application is running. However, when the application is stopped, the cache entries remain in cache indefinitely because cache eviction is handled on the client side by Redisson. TTL is configured in the application.yml file.
Is it possible to configure a TTL for cache entries also on the Redis side, ensuring that the cache is cleared even when the application is not running?
Ideally, each individual entry within a hash storing a specific entity should be marked with HEXPIRE. This is particularly important because we plan to use a unique hibernate.cache.region_prefix for each deployment, due to backward-incompatible changes in our entities.
I expected the TTL to be set in Redis, but it is absent, confirming that it is indeed managed by Redisson:
spring:
jpa:
properties:
hibernate:
cache:
use_second_level_cache: true
region_prefix: l2_cache
region:
factory_class: org.redisson.hibernate.RedissonRegionFactory
redisson:
entity:
expiration:
time_to_live: 20000
max_idle_time: 20000
fallback: true
config: redisson.yml
Entity:
@Entity
@Cacheable
@Cache(region = "someEntityCache", usage = CacheConcurrencyStrategy.READ_WRITE)
public class SomeEntity {
If you're using RedissonRegionFactory
the way you've specified in your yaml, then you'd need to use scripted eviction, i.e., implement an org.redisson.eviction.EvictionScheduler
bean to cleanup the keys.
It seems you want to evict the entries natively, without a spring task.
According to their docs, there are 6 ways to do this, but 5 of them require redisson pro.
The one way they offer that that doesn't require pro, but also allows native eviction (without a spring task) to clean entries on the redis side, is RedissonRegionNativeFactory
. So, try setting spring.jpa.properties.hibernate.cache.region.factory_class
to org.redisson.hibernate.RedissonRegionNativeFactory
.
Alternatively, I think you can programmatically set TTLs on an entry with
RBucket<?> bucket = redissonClient.getBucket(key);
bucket.expire(ttl, timeUnit);