5

I am using Spring Data Cache using Redis as the cache manager. The config is like:

    return RedisCacheManager.builder(redisConnectionFactory)
        .cacheDefaults(
            RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(SerializationPair.fromSerializer(RedisSerializer.string()))
                .serializeValuesWith(SerializationPair.fromSerializer(RedisSerializer.json()))
        )
        .build()

Let's imagine a very naive example using spring data cache:

@Cacheable(...)
MyPOJO compute() { ... }

However, the RedisSerializer.json() is indeed a GenericJackson2JsonRedisSerializer. Thus, IMHO it will store things like {"hello":"world","@class":"com.my.name.some.package.MyPOJO"}. That @class: ... part is quite long and a waste of precious memory in Redis. Moreover, IMHO Spring Data Cache should be smart enough to realize that the value type is indeed MyPOJO, so it should not need to store that "@class".

Thus my question is: How to avoid storing class names in serialized JSON which waste lots of space, in Spring Data Cache + Redis CacheManager?

Thanks for any suggestions!

ch271828n
  • 15,854
  • 5
  • 53
  • 88

1 Answers1

1

Have you looked into the implementation of GenericJackson2JsonRedisSerializer? It looks like the default object mapper is configured to use Jacksons polymorphic type features. But there is also an option to pass a custom ObjectMapper like this:

SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer(objectMapper))

You can configure and pass a custom Jacksons Object Mapper, with or without type information. There are several ways to configure how type information is stored (if you actually need it): https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization

In earlier versions there was no type information configured by Spring as seen here: How to use GenericJackson2JsonRedisSerializer It looks like this has been changed in more recent versions. However, the option still remains to configure your Serializer as required.

  • Hi thank you so much! Indeed I have tried to create a brand new Object Mapper using `ObjectMapper().registerKotlinModules()`, and then, strangely, it does not give a MyPOJO but instead give a `LinkedHashMap`. I really do not know what happens... – ch271828n Jan 31 '22 at 00:14
  • Down vote. Deserialization will not work without type information. – KevinBui Oct 07 '22 at 14:01