jackson-databind icon indicating copy to clipboard operation
jackson-databind copied to clipboard

Redis ObjectMapper with kotlin data class don't work without DefaultTyping.EVERYTHING

Open florianLaforest opened this issue 3 months ago • 1 comments

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

florianLaforest avatar Mar 13 '24 08:03 florianLaforest

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.

cowtowncoder avatar Mar 13 '24 18:03 cowtowncoder

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. ^_^

florianLaforest avatar Mar 19 '24 11:03 florianLaforest