skip to Main Content

I am trying to implement Hibernate second level caching in a Spring boot project using Redisson.

I have followed this blog as a reference

https://pavankjadda.medium.com/implement-hibernate-2nd-level-cache-with-redis-spring-boot-and-spring-data-jpa-7cdbf5632883

Also i am trying to initialize the RedissionClient programmatically and not through declaratively /through a config file

Created a spring bean to be initialized which should create the RedissonClient instance.

    @Configuration
@Lazy(value = false)
public class RedissonConfig {
    
    @Bean
    public RedissonClient redissionClient() {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        return Redisson.create(config);
        
    }

}

However this bean is never intialized and i get the following error while application startup.

Caused by: org.hibernate.cache.CacheException: Unable to locate Redisson configuration
at org.redisson.hibernate.RedissonRegionFactory.createRedissonClient(RedissonRegionFactory.java:107) ~[redisson-hibernate-53-3.12.1.jar:3.12.1]
at org.redisson.hibernate.RedissonRegionFactory.prepareForUse(RedissonRegionFactory.java:83) ~[redisson-hibernate-53-3.12.1.jar:3.12.1]

It seems Spring boot Hibernate still trying to load the Redisson config through a config file.

is it possible to load the Redission config in spring boot programmatically ?

Best Regards,

Saurav

2

Answers


  1. It is possible, but then you need to provide a custom implementation of RegionFactory to Hibernate, which can extends RedissonRegionFactory but uses your own client instance.

    Login or Signup to reply.
  2. I just did exactly this, here is how:

    1. you need a custom RegionFactory that is similar to the JndiRedissonRegionFactory but gets its RedissonClient injected somehow.

    2. an instance of this Class, fully configured, is put into the hibernate-properties map. Hibernates internal code is flexible: if the value of hibernate.cache.region.factory_class is a string it is treated as a FQDN. If it is an instance of Class<?>, it will be instantiated. If it is an Object, it will be used.

    Spring offers a rather simple way to customize hibernate properties with a bean:

    @AutoConfiguration(after = RedissonAutoConfiguration.class, before = JpaAutoConfiguration.class)
    @ConditionalOnProperty("spring.jpa.properties.hibernate.cache.use_second_level_cache")
    public class HibernateCacheAutoConfiguration {
        @Bean
        public HibernatePropertiesCustomizer setRegionFactory(RedissonClient redisson) {
            return hibernateProperties -> hibernateProperties.put(AvailableSettings.CACHE_REGION_FACTORY, new SpringBootRedissonRegionFactory(redisson));
        }
    }
    

    My RegionFactory is really simple:

    @AllArgsConstructor
    public class SpringBootRedissonRegionFactory extends RedissonRegionFactory {
    
        private RedissonClient redissonClient;
    
        @Override
        protected RedissonClient createRedissonClient(Map properties) {
            return redissonClient;
        }
    
        @Override
        protected void releaseFromUse() {
        }
    
    }
    

    I used the redisson-starter to get a RedissonClient, hence the reference to RedissonAutoConfiguration, but you could just create an instance by hand.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search