How to create RedisCacheManager in spring-data 2.0.x
Asked Answered
B

3

8

I'm migrating my application from spring boot 1.5.x to 2.0.x. I want to keep jedis but I have a problem with the instantiation of RedisCacheManager.

Now constructor signature is

RedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration)

But before it was:

RedisCacheManager(RedisOperations redisOperations)

I define this bean having only RedisTemplate in scope:

@Bean
public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
    HandleRedisCacheManager redisCacheManager = new HandleRedisCacheManager(redisTemplate);
    redisCacheManager.setUsePrefix(true);
    return redisCacheManager;
}

How is it supposed to be created now?

Bountiful answered 19/7, 2018 at 8:46 Comment(0)
K
7

It doesn't accept a RedisTemplate anymore. So try this:

@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory,
                                      ResourceLoader resourceLoader) {
    RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager
            .builder(redisConnectionFactory)
            .cacheDefaults(determineConfiguration(resourceLoader.getClassLoader()));
    List<String> cacheNames = this.cacheProperties.getCacheNames();
    if (!cacheNames.isEmpty()) {
        builder.initialCacheNames(new LinkedHashSet<>(cacheNames));
    }
    return builder.build();
}

private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(
        ClassLoader classLoader) {
    if (this.redisCacheConfiguration != null) {
        return this.redisCacheConfiguration;
    }
    CacheProperties.Redis redisProperties = this.cacheProperties.getRedis();
    RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();

    ObjectMapper mapper = new Jackson2ObjectMapperBuilder()
            .modulesToInstall( new SimpleModule().addSerializer( new NullValueSerializer(null)) )
            .failOnEmptyBeans( false )
            .build();
    mapper.enableDefaultTyping( ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

    GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer( mapper );

    //get the mapper b/c they registered some internal modules
    config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer));;

    if (redisProperties.getTimeToLive() != null) {
        config = config.entryTtl(redisProperties.getTimeToLive());
    }
    if (redisProperties.getKeyPrefix() != null) {
        config = config.prefixKeysWith(redisProperties.getKeyPrefix());
        config = config.computePrefixWith(cacheName -> redisProperties.getKeyPrefix() + cacheName + "::");
    }
    if (!redisProperties.isCacheNullValues()) {
        config = config.disableCachingNullValues();
    }
    if (!redisProperties.isUseKeyPrefix()) {
        config = config.disableKeyPrefix();
    }
    return config;
}
Kuska answered 8/8, 2018 at 22:26 Comment(1)
If it stopped accepting RedisTemplate as parametr to constructor - does the logic of the code by omitting it changed? Or is the same as it was in SpringBoot 1.5?Maidenhood
P
20

try following code , it works for me on spring-boot 2.1.0.RELEASE

@Bean
public RedisCacheManager redisCacheManager(LettuceConnectionFactory lettuceConnectionFactory) {
    RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
            .disableCachingNullValues()
            .entryTtl(Duration.ofHours(1))
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
    redisCacheConfiguration.usePrefix();

   return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(lettuceConnectionFactory)
                    .cacheDefaults(redisCacheConfiguration).build();

}    
Peck answered 10/1, 2019 at 8:31 Comment(2)
redisCacheConfiguration.usePrefix(); does not make any sense. It is a method that just returns a boolean. The class is immutable so setUsePrefix needs to have some equivalent in the builder. It seems as usePrefix defaults to true if not explicitly disabled with RedisCacheConfiguration#disableKeyPrefix()Exterritorial
@MikaelVandmo The way I read the code, usePrefix defaults to false. It goes to true if you call .prefixKeysWith(String) or .computePrefixWith()Bliss
K
7

It doesn't accept a RedisTemplate anymore. So try this:

@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory,
                                      ResourceLoader resourceLoader) {
    RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager
            .builder(redisConnectionFactory)
            .cacheDefaults(determineConfiguration(resourceLoader.getClassLoader()));
    List<String> cacheNames = this.cacheProperties.getCacheNames();
    if (!cacheNames.isEmpty()) {
        builder.initialCacheNames(new LinkedHashSet<>(cacheNames));
    }
    return builder.build();
}

private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(
        ClassLoader classLoader) {
    if (this.redisCacheConfiguration != null) {
        return this.redisCacheConfiguration;
    }
    CacheProperties.Redis redisProperties = this.cacheProperties.getRedis();
    RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();

    ObjectMapper mapper = new Jackson2ObjectMapperBuilder()
            .modulesToInstall( new SimpleModule().addSerializer( new NullValueSerializer(null)) )
            .failOnEmptyBeans( false )
            .build();
    mapper.enableDefaultTyping( ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

    GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer( mapper );

    //get the mapper b/c they registered some internal modules
    config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer));;

    if (redisProperties.getTimeToLive() != null) {
        config = config.entryTtl(redisProperties.getTimeToLive());
    }
    if (redisProperties.getKeyPrefix() != null) {
        config = config.prefixKeysWith(redisProperties.getKeyPrefix());
        config = config.computePrefixWith(cacheName -> redisProperties.getKeyPrefix() + cacheName + "::");
    }
    if (!redisProperties.isCacheNullValues()) {
        config = config.disableCachingNullValues();
    }
    if (!redisProperties.isUseKeyPrefix()) {
        config = config.disableKeyPrefix();
    }
    return config;
}
Kuska answered 8/8, 2018 at 22:26 Comment(1)
If it stopped accepting RedisTemplate as parametr to constructor - does the logic of the code by omitting it changed? Or is the same as it was in SpringBoot 1.5?Maidenhood
K
0
@Bean
  public CacheManager cacheManager() {
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
            .disableCachingNullValues()
            .entryTtl(Duration.ofHours(1))
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
      redisCacheConfiguration.usePrefix();
      return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(jedisConnectionFactory())
          .cacheDefaults(redisCacheConfiguration).build();
}
Kidd answered 5/4, 2023 at 12:28 Comment(1)
Hello, please add some details about your answer. E.g. what were our changes, why did you make these changes, etc.Latin

© 2022 - 2024 — McMap. All rights reserved.