I am using Spring Data Redis in order to cache some data using @Cacheable
. I have multiple types of objects that need to be cached and I need the data from Redis to be in JSON format. I know that, by default, the serializer used is JdkSerializationRedisSerializer
, but with is the cached data is not human readable.
I order to save the data in JSON format I wanted to use GenericJackson2JsonRedisSerializer
and I’ve created a custom ObjectMapper
too:
public RedisTemplate<Object, Object> redisTemplate (RedisConnectionFactory cf) {
ObjectMapper objectMapper = new Jackson2ObjectMapperBuilder().failOnEmptyBeans(false)
.failOnUnknownProperties(false)
.indentOutput(false)
.serializationInclusion(JsonInclude.Include.NON_NULL)
.modules(
// Optional
new Jdk8Module(),
// Dates/Times
new JavaTimeModule()
)
.featuresToDisable(
SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS,
SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS
).build();
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(objectMapper);
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(cf);
redisTemplate.setKeySerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
return redisTemplate;
Using this RedisTemplate
doesn’t work and I always get back this error:
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to <some class>
As I understood, when deserializing, Jackson doesn’t know the type of the specific object since it’s Object
and creates a LinkedHashMap
to hold the data. Maybe I am wrong with this, but how can I achieve saving the cached data as JSON for multiple types of objects with @Cacheble?
2
Answers
You are right, you can achieve saving multiple types with
GenericJackson2JsonRedisSerializer
. But in your example, you provide customObjectMapper
toGenericJackson2JsonRedisSerializer
andGenericJackson2JsonRedisSerializer
doesn’t configure Jackson’s default typing for you (you can check default constructor logic inGenericJackson2JsonRedisSerializer
). You have to tune it on your own and add this to your ObjectMapperThis will include type information to JSON. Like this
Since 2.10 ObjectMapper better to use