-
Notifications
You must be signed in to change notification settings - Fork 4
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 of value classes implementing an interface uses underlying type of value class for array polymorphism #230
Comments
Can you attach some more detailed code? |
created a demonstration project: |
It works for the import com.fasterxml.jackson.annotation.JsonTypeInfo
import com.fasterxml.jackson.annotation.JsonValue
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import java.util.*
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
sealed interface Id {
@get:JsonValue
val value: UUID
}
data class PersonId(override val value: UUID) : Id
data class ThingId(override val value: UUID) : Id
data class PersonOrThing(val id: Id)
class GH230 {
@Test
fun `test serialization of value class`() {
val id = PersonId(UUID.randomUUID())
val json = jacksonObjectMapper().writeValueAsString(id)
assertEquals("[\"PersonId\",\"${id.value}\"]", json)
}
@Test
fun `test serialization of data class with value class attribute`() {
val obj = PersonOrThing(PersonId(UUID.randomUUID()))
val json = jacksonObjectMapper().writeValueAsString(obj)
assertEquals("{\"id\":[\"PersonId\",\"${obj.id.value}\"]}", json)
}
@Test
fun `test deserialization of value class by string`() {
val id = PersonId(UUID.randomUUID())
val deserialized = jacksonObjectMapper().readValue("[\"PersonId\",\"${id.value}\"]", Id::class.java)
assertEquals(id, deserialized)
}
@Test
fun `test deserialization of data class with value class attribute by string`() {
val obj = PersonOrThing(PersonId(UUID.randomUUID()))
val deserialized = jacksonObjectMapper().readValue("{\"id\":[\"PersonId\",\"${obj.id.value}\"]}", PersonOrThing::class.java)
assertEquals(obj, deserialized)
}
} However, I have done some research and could not determine if this issue can be resolved. |
How about something like this:
And changing the KotlinSerializers class like that:
|
https://github.com/NilsWild/jackson-module-kogera with some improvements to not break custom serialization and deserialization |
When a value class object is serialized the unterlying type is used. If the value class implments an interface, array polymorphism is used to store the type. However the type is set to the underlying type instead of the value class type. I am not sure if it's possible to fix this or how as the value classes are inlined.
Example:
A Name object gets serialized to
["String","name"]
when deserializing it can not be mapped for obvious reasons.
Providing
["Name","name"]
on the other hand can be deserialized. So the issue is only with serialization.The text was updated successfully, but these errors were encountered: