jackson-databind
jackson-databind copied to clipboard
Redis ObjectMapper with kotlin data class don't work without DefaultTyping.EVERYTHING
Describe your Issue
In version 2.17, DefaultTyping.EVERYTHING has been deprecated. I'm trying to change my redis mapper but without success. I can't get it to work without DefaultTyping.EVERYTHING.
Here's my ObjectMapper:
@Bean("redisObjectMapper")
fun objectMapper(): ObjectMapper {
val objectMapper = ObjectMapper().registerKotlinModule()
return objectMapper.activateDefaultTyping(
BasicPolymorphicTypeValidator.builder()
.allowIfBaseType(Any::class.java)
.build(),
ObjectMapper.DefaultTyping.EVERYTHING,
)
}
And my RedisTemplate :
@Bean
fun redisTemplate(
factory: RedisConnectionFactory,
@Qualifier("redisObjectMapper") objectMapper: ObjectMapper,
): RedisTemplate<String, Any> {
val template = RedisTemplate<String, Any>()
template.setDefaultSerializer(GenericJackson2JsonRedisSerializer(objectMapper))
template.keySerializer = StringRedisSerializer()
template.hashKeySerializer = StringRedisSerializer()
template.connectionFactory = factory
return template
}
There was already an issue about support for the kotlin data class: https://github.com/FasterXML/jackson-databind/issues/2349
I really wish Redis mapper (and similar use cases) used plain old @JsonTypeInfo
and wrapper class like so:
class CacheValue {
@JsonTypeInfo(.... use class name etc ...)
public Object value;
}
which should work the way to add type information for all values, without resorting to default typing.
Default typing and direct root value without wrapper is next to impossible to make work; and DefaultTyping.EVERYTHING
is a nasty work-around.
Having said that, while deprecated, this functionality WILL REMAIN for all of 2.x, only to be removed from Jackson 3.0. And there's time to work through the issue for that transition.
All right, I've replaced EVERYTHING by JAVA_LANG_OBJECT and JsonTypeInfo as PROPERTY
@Bean("redisObjectMapper")
fun objectMapper(): ObjectMapper {
val objectMapper = ObjectMapper().registerKotlinModule()
return objectMapper.activateDefaultTyping(
BasicPolymorphicTypeValidator.builder()
.allowIfBaseType(Any::class.java)
.build(),
ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT,
JsonTypeInfo.As.PROPERTY,
)
}
Then I added the JsonTypeInfo to all my classes that needed it
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
I'm going to miss the EVERYTHING, it made things so much simpler. ^_^