Search code examples
javaspring-bootredisspring-data-redisspring-session

FindByIndexNameSessionRepository cannot be null in Spring Boot


I am trying to implement remember function for my Spring Security Application. And I used Redis also. I configured, SpringSessionBackedSessionRegistry beans. But when I try to @Autowired FindByIndexNameSessionRepository I got the following error,

Caused by: java.lang.IllegalArgumentException: sessionRepository cannot be null

The code is as follows,

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private FindByIndexNameSessionRepository<? extends Session> sessionRepository;
    
    @Bean
    public SpringSessionBackedSessionRegistry sessionRegistry() {
        return new SpringSessionBackedSessionRegistry(this.sessionRepository);
    }
}

Handler.java

@Component
public class Handler {

    private @Autowired SessionRegistry sessionRegistry;
    private @Autowired FindByIndexNameSessionRepository<? extends Session> sessionRepository;
    
}

And Redis Session Configuration,

@Configuration
@EnableSpringHttpSession
public class SessionConfig {

    private final RedisConnectionFactory redisConnectionFactory;

    public SessionConfig(ObjectProvider<RedisConnectionFactory> redisConnectionFactory) {
        this.redisConnectionFactory = redisConnectionFactory.getIfAvailable();
    }
    
    @Bean
    public RedisOperations<String, Object> sessionRedisOperations() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(this.redisConnectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }

    @Bean
    public RedisSessionRepository redisSessionRepository(RedisOperations<String, Object> sessionRedisOperations) {
        return new RedisSessionRepository(sessionRedisOperations);
    }
}

I get errors like,

Caused by: java.lang.IllegalArgumentException: sessionRepository cannot be null Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.session.security.SpringSessionBackedSessionRegistry]: Circular reference involving containing bean 'securityConfig' - consider declaring the factory method as static for independence from its containing instance. Factory method 'sessionRegistry' threw exception; nested exception is java.lang.IllegalArgumentException: sessionRepository cannot be null Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionRegistry' defined in class path resource [SecurityConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.session.security.SpringSessionBackedSessionRegistry]: Circular reference involving containing bean 'securityConfig' - consider declaring the factory method as static for independence from its containing instance. Factory method 'sessionRegistry' threw exception; nested exception is java.lang.IllegalArgumentException: sessionRepository cannot be null

Also it says,

No beans of 'FindByIndexNameSessionRepository<? extends Session>' type found.

So what I am doing wrong here?


Solution

  • Maybe, I am not sure, because this circular dependency error...

    In any case, the problem probably is happening because you do not actually have a FindByIndexNameSessionRepository injected in your Spring context, at least not the one you are trying to configure, but a SessionRepository, because you are defining a bean of type RedisSessionRepository and this interface implements SessionRepository, not FindByIndexNameSessionRepository. Please, try to use a RedisIndexedSessionRepository instead, something like:

    @Configuration
    @EnableSpringHttpSession
    public class SessionConfig {
    
        private final RedisConnectionFactory redisConnectionFactory;
    
        public SessionConfig(ObjectProvider<RedisConnectionFactory> redisConnectionFactory) {
            this.redisConnectionFactory = redisConnectionFactory.getIfAvailable();
        }
        
        @Bean
        public RedisOperations<String, Object> sessionRedisOperations() {
            RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
            redisTemplate.setConnectionFactory(this.redisConnectionFactory);
            redisTemplate.setKeySerializer(new StringRedisSerializer());
            redisTemplate.setHashKeySerializer(new StringRedisSerializer());
            return redisTemplate;
        }
    
        @Bean
        public FindByIndexNameSessionRepository redisSessionRepository(RedisOperations<String, Object> sessionRedisOperations) {
            return new RedisIndexedSessionRepository(sessionRedisOperations);
        }
    }