Migrate Spring boot data Redis session to v3.0
Migrating spring boot data redis from 2.7 to 3.0 seems to be only about renaming properties (see guide) from spring.redis.
to spring.data.redis.
, but there are other things to change if you are using redis for sessions.
The official documentation spring boot data Redis 3.0 says that spring.session.store-type=redis
can still be used in application.properties
, but in reality that has been deprecated. It seems like @EnableRedisHttpSession
is needed to enable Redis to store sessions.
As a consequence, spring.session.redis.namespace
and spring.session.timeout
have to be passed to the @EnableRedisHttpSession
annotation.
In case the Redis namespace and timeout are defined dynamically via properties per environment and you don't want to hardcode them, this is a solution I found by defining a RedisHttpSessionConfiguration
configuration and overriding the getters.
package io.github.elvisciotti.config.redis;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.FlushMode;
import org.springframework.session.SaveMode;
import org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration;
import java.time.Duration;
@Configuration
public class RedisHttpConfig extends RedisHttpSessionConfiguration {
@Value("${spring.session.redis.namespace}")
private String namespace;
@Value("${spring.session.timeout}")
private Duration inactiveInterval;
@Override
protected Duration getMaxInactiveInterval() {
return inactiveInterval;
}
@Override
protected String getRedisNamespace() {
return namespace;
}
// you can remove it if you accept the defaults below
@Override
protected FlushMode getFlushMode() {
return FlushMode.ON_SAVE;
}
@Override
protected SaveMode getSaveMode() {
return SaveMode.ON_SET_ATTRIBUTE;
}
}
This code reads values from
spring.session.redis.namespace=yournamspace.v1
spring.session.timeout=12h
Also, in case you have problems with SessionRepository
being used as Bean in your services, you can solve by returning the RedisIndexedSessionRepository
. This might change with future spring versions
@Configuration
public class RedisConfig {
@Bean
@Primary
public SessionRepository redisIndexedSessionRepository(RedisTemplate<String, Object> redisTemplate) {
return new RedisIndexedSessionRepository(redisTemplate);
}
@Bean
public RedisTemplate<String, Object> redisDefaultTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(new JdkSerializationRedisSerializer());
return template;
}
}
Other references: