Your question I have checked issues and docs and could not find solution.
The follwing code properly serialize object (Component) to string, but deserialization from string back to insgtances of Component doesn't work.
Any suggestions how to do it, without removing delegations?
Thanks :)
import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonSubTypes.Type
import com.fasterxml.jackson.annotation.JsonTypeInfo
import com.fasterxml.jackson.core.json.JsonReadFeature
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.json.JsonMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonSubTypes(
value = [
Type(value = Space::class, name = Space.TYPE),
Type(value = Command::class, name = Command.TYPE),
]
)
interface Component {
var id: String
@get:JsonIgnore
val type: String
}
data class Command(
val value: String,
val component: Component
) : Component by component {
override val type: String
get() = TYPE
companion object {
const val TYPE = "command"
}
}
data class Space(
val space: String,
private val component: Component
) : Component by component {
override val type: String
get() = TYPE
companion object {
const val TYPE = "space"
}
}
data class Info(
override var id: String,
override val type: String = "",
) : Component
class FooTest {
// private val objectMapper = ObjectMapperFactory.createObjectMapper(emptyList())
private val objectMapper = JsonMapper.builder()
.addModule(KotlinModule())
.serializationInclusion(JsonInclude.Include.NON_NULL)
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)
.enable(JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER)
.build()
@Test
fun `should deserialize`() {
val value = objectMapper.writeValueAsString(
Command(
value = "text",
component = Info(id = "d")
)
)
val obj = objectMapper.readValue(value, Component::class.java)
assertThat(value).isEqualTo(obj)
}
}
Error
com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'Info' as a subtype of `<>.<>.<>.<>.jackson.Component`: known type ids = [command, space] (for POJO property 'component')
at [Source: (String)"{"type":"command","value":"text","component":{"type":"Info","id":"d"},"id":"d"}"; line: 1, column: 54] (through reference chain: <>.<>.<>.<>.jackson.Command["component"])