javaspring-bootredisredissonsecond-level-cache

Spring Boot with Redis as a second-level cache. Any way to set TTL on cache entries in Redis so they are deleted when Redisson is not running?


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: enter image description here

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 {

Solution

  • 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);