-
Notifications
You must be signed in to change notification settings - Fork 175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Serialization and Deserialization of Kotlin data class
fails on PolymorphicTypeValidator with Any
#819
Comments
Kotlin issues belong under |
Created a PR because I found a problem with Will check again after this is merged. |
Checked. This is a new feature addition and an implementation policy should be discussed. @effx13 has submitted
As for the implementation, the base class of import com.fasterxml.jackson.annotation.JsonCreator
import com.fasterxml.jackson.annotation.JsonTypeInfo
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import kotlin.test.Test
class GitHub819 {
@JvmInline
value class ServerName(val value: String) {
companion object {
@JsonCreator
@JvmStatic
fun fromValue(value: String): ServerName {
return ServerName(value)
}
}
}
data class TestDto(
val serverName: ServerName
)
// on EVERYTHING
@Test
fun everything() {
val objectMapper = ObjectMapper()
.registerKotlinModule()
.registerModule(JavaTimeModule())
.activateDefaultTyping(
BasicPolymorphicTypeValidator.builder().allowIfBaseType(Any::class.java).build(),
ObjectMapper.DefaultTyping.EVERYTHING,
JsonTypeInfo.As.PROPERTY,
)
val serverName = ServerName("TEST")
val testDto = TestDto(serverName)
val serialized = objectMapper.writeValueAsString(testDto)
// -> {"@class":"com.fasterxml.jackson.module.kotlin.test.github.GitHub819$TestDto","serverName":["com.fasterxml.jackson.module.kotlin.test.github.GitHub819$ServerName","TEST"]}
println(serialized)
val deserialized = objectMapper.readValue(serialized, Any::class.java) // Because of RedisSerializer
// -> TestDto(serverName=ServerName(value=TEST))
println(deserialized)
}
} As a side note, as far as the prototype is concerned, I feel that it would be difficult to implement in any other way. |
@k163377 I agree, as you said, in BasicPolymorphicTypeValidator it should come out as |
👍
First, a version that incorporates the fix for the bug is required(2.18.1 or later). After that, you may be able to solve your use case by setting up a custom serializer based on As for the |
Quick note: 2.18.1 not yet released; will be released in near future (2-3 weeks), but need to combine with other fixes. |
@cowtowncoder First, I think the work is basically just to change the parent class from I was also checking the implementation of I found that jackson-module-kotlin/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinSerializers.kt Lines 30 to 35 in 9d4ad6a
|
Ok, first, missing |
Second: And yes, testing over different combinations makes sense. FWTW, I am not 100% convinced original reporter really should (have to) use Default Typing -- almost in every case it'd be much better to use a Wrapper class with
to avoid complexities of Default Typing applicability and need for But for some reason Redis users keep on relying on Default Typing it seems. |
@cowtowncoder |
I did a little research and found it quite difficult to support this. The cause is that the The following is what I have confirmed. First, the direct cause is that The Theoretically, this problem can be solved if one of the following can be accomplished
Of these, I consider 1 to be impractical because its sphere of influence is too broad. As for 3, I feel it will take time to implement and validate due to lack of knowledge about |
Once again, I think Once again, submitted should consider wrapper type I outlined earlier. Or, alternatively specify "base type" on writing, instead of relying on runtime exact (implementation) type: something like
because otherwise type used for determining polymorphic nature (or not) is I hope above makes sense. |
Btw, I am not arguing you should work on this @k163377 . But as usual, if there was any way to reduce this to Java-only reproduction, I could have a look. I realize this may not be possible, but if it is. |
In Lines 62 to 71 in 9d4ad6a
Processes related to |
Hmmh. But my initial thinking is that no converter should be used for base type as that is what polymorphic handling is based on. That is, for example:
in this case, "baseType" is (and needs to be) "Value" serializer is based on actual type (unless But So no converter should be applied to "baseType": it is only used to locate I hope this makes more sense. |
Search before asking
Describe the bug
When trying to deserialize class that contains kotlin value class, Jackson throws
InvalidTypeIdException
withmissing type id property '@class'
onObjectMapper.DefaultTyping.NON_FINAL
Despite adding
@JsonCreator
annotation, I got the same result.And trying to serialize above class with
ObjectMapper.DefaultTyping.NON_FINAL
, Jackson throwsJsonMappingException
withclass ServerName cannot be cast to class java.lang.String (ServerName is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap') (through reference chain: TestDto["serverName"])
I'm using PolymorphicTypeValidator and Any class to do serialization and deserialization in Redis. But no matter what settings and annotations I use, the serialization and deserialization fails.
Version Information
JVM 21
Kotlin 1.8
jackson-core:2.17.2
jackson-databind:2.17.2
jackson-annotations:2.17.2
jackson-datatype-jsr310:2.17.2
jackson-module-kotlin:2.17.2
Reproduction
Expected behavior
No response
Additional context
No response
The text was updated successfully, but these errors were encountered: