saurav
saurav

Reputation: 5926

Programmatic RedissonClient in Spring boot project

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

Upvotes: 2

Views: 3748

Answers (3)

Nikita Koksharov
Nikita Koksharov

Reputation: 10783

You can use Redisson Hibernate JndiRedissonRegionFactory instead.

Register RedissonClient instance in JNDI registry in Spring to make it available for JndiRedissonRegionFactory.

in hibernate configuration define:

hibernate.cache.region.factory_class = org.redisson.hibernate.JndiRedissonRegionFactory
hibernate.cache.redisson.jndi_name = <redisson instance name registered in Spring>

Upvotes: 0

Laures
Laures

Reputation: 5489

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.

Upvotes: 1

Christian Beikov
Christian Beikov

Reputation: 16400

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.

Upvotes: 0

Related Questions