Hervé Darritchon
Hervé Darritchon

Reputation: 461

Custom spring-session repository Redis with Dynomite

In our infrastructure, we are using Redis with Dynomite to have a replication over datacenter and high availability. One of our app is in Java and we are mainly using spring ecosystem.

In this app, we manage session using spring-session and we use the Redis cluster to store the sessions.

Spring session is using pub/sub commands which are not allowed in a Dynomite context so we need to to a custom repository.

I tried to do so but I have an issue with spring-boot and autoconfiguration class.

please find below some part of our code.

dependencies in a build.gradle

val springBootVersion = "2.1.4.RELEASE"
val springSessionDataRedisVersion = "2.1.5.RELEASE"

implementation("org.springframework.boot:spring-boot-starter-security:$springBootVersion")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf:$springBootVersion")
implementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
implementation("org.springframework.boot:spring-boot-starter-data-redis:$springBootVersion")
implementation("org.springframework.session:spring-session-data-redis:$springSessionDataRedisVersion")

Our configuration class to override the sessionRepository with our custom one

@Configuration
@EnableRedisHttpSession
public class SessionConfig extends AbstractHttpSessionApplicationInitializer     {

@Bean
public SessionRepository sessionRepository() {
    return new RedisDynoSessionRepository();
    }
}

The sessionRepository custom class

public class RedisDynoSessionRepository implements SessionRepository {
...
}

When we run our app, we a collision in the bean because the app finds that the bean session repository is already known.

org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'sessionRepository' defined in class path resource [com/orange/ccmd/spring/redis/SessionConfig.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=sessionConfig; factoryMethodName=sessionRepository; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/orange/ccmd/spring/redis/SessionConfig.class]] for bean 'sessionRepository': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration; factoryMethodName=sessionRepository; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class]] bound.

I am looking for a way to bypass this problem may be with unregistring the bean ?

Thanks for you help.


[EDIT]

I tried the @Primary on the bean and it doesn't work. If I named my bean differently, Spring uses the standard bean not my custom new one. If I named it the same way, I have a conflict error. If I put the override bean configuration (spring.main.allow-bean-definition-overriding=true), I have an error because the 2 beans don't have the same type. Which is what I intend to do because I don't want the messaging stuff in my repo.

Upvotes: 2

Views: 3850

Answers (1)

Hervé Darritchon
Hervé Darritchon

Reputation: 461

I have opened an issue on the github Spring-sesssion repo (https://github.com/spring-projects/spring-session/issues/1406).

I had my answer. In fact, I did it the wrong way. As it is stated in the documentation. I have to use the @EnableSpringHttpSessionannotation to register my custom bean instead of the @EnableRedisHttpSession.

And it works, I don't have any issue during the app initialization.

Upvotes: 2

Related Questions