I am trying to deserialize object using com.fasterxml.jackson.databind doing this way:
val restoredProject = validationSessionHelperImpl.objectMapper2.readValue<com.fmetric.validation.api.Project>(validationData.projectJSON!!)
detailed code here https://gist.github.com/iva-nova-e-katerina/f09cce0ade8a9b9a69ab9b52cbb1b0ea and got following error:
com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'java.util.ArrayList' as a subtype of `java.util.List<com.fmetric.regulation.api.data.property.PropertyType>`: Configured `PolymorphicTypeValidator` (of type `com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator`) denied resolution
at [Source: (StringReader); line: 1, column: 237] (through reference chain: com.fmetric.validation.api.Project["rootBrick"]->com.fmetric.validation.api.Brick["type"]->com.fmetric.regulation.api.data.brick.BrickTypeFull["propertyTypes"])
at com.fasterxml.jackson.databind.exc.InvalidTypeIdException.from(InvalidTypeIdException.java:43)
at
The source JSON string is here https://gist.github.com/iva-nova-e-katerina/fa5ce8ddb03fb9db2b0dde930a6dbd5d
I must tell you something about classes hierarchy
data class Brick(
val id: UUID?,
val name: String,
val type: BrickType,
val propertyValues: List<ProjectBrickPropertyValue<*>>,
)
open class BrickType(
open val id: UUID?,
open val name: String?
)
class BrickTypeFull(
id: UUID?,
name: String?,
val propertyTypes: List<PropertyType>?
) : BrickType (id,name){
This issue is related to another my question UnrecognizedPropertyException during deserialization with com.fasterxml.jackson.databind.ObjectMapper
Could you help me to serialize/deserialize an object aggregated with the object of inherited type BrickTypeFull ?
CodePudding user response:
Here is a complete example
package com.example
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator
import com.fasterxml.jackson.module.kotlin.KotlinModule
import java.util.*
const val payload: String = """
{
"id":"f0156c1d-238b-4cfa-a5ba-17a3e2c9dc55",
"name":"Здание",
"type":["com.example.BrickTypeFull",{
"id":"24073daa-4193-4f16-bed2-d8ef226a8715",
"name":"Здание",
"propertyTypes":["java.util.ArrayList",[
{"id":"ed4e58f5-722e-4752-bf24-1b34dc5fdcd5","category":"BOOLEAN","name":"Cтатус архитектурного памятника","description":"Статус архитектурного памятника","brickTypeId":"24073daa-4193-4f16-bed2-d8ef226a8715","regulationId":null,"dictionaryValueId":null,"options":null},
{"id":"ed4e58f5-722e-4752-bf24-1b34dc5fdcd5","category":"BOOLEAN","name":"Cтатус архитектурного памятника","description":"Статус архитектурного памятника","brickTypeId":"24073daa-4193-4f16-bed2-d8ef226a8715","regulationId":null,"dictionaryValueId":null,"options":null}
]]
}]
}
"""
data class Brick(
val id: UUID?,
val name: String,
val type: BrickType,
)
open class BrickType(
open val id: UUID?,
open val name: String?
)
class BrickTypeFull(
id: UUID?,
name: String?,
val propertyTypes: List<PropertyType>?
) : BrickType(id, name)
@JsonIgnoreProperties(ignoreUnknown = true)
data class PropertyType(
val id: UUID,
val category: String,
val name: String,
val description: String,
val brickTypeId: UUID,
val regulationId: UUID?,
val dictionaryValueId: UUID?,
)
fun main(args: Array<String>) {
ObjectMapper().apply {
registerModule(KotlinModule.Builder().build())
activateDefaultTyping(
BasicPolymorphicTypeValidator.builder()
.allowIfSubType("com.example")
.allowIfSubType("java.util.ArrayList")
.build(),
ObjectMapper.DefaultTyping.NON_FINAL
)
}.also {
val result = it.readerFor(Brick::class.java).readValue<Brick>(payload)
println((result.type as BrickTypeFull).propertyTypes?.get(0))
}
}
Probably you forgot to add .allowIfSubType("java.util.ArrayList")
to your deserialiser.
CodePudding user response:
Deserialization works with following Validator
val ptv: PolymorphicTypeValidator = BasicPolymorphicTypeValidator.builder()
.allowIfSubType("com.fmetric.regulation.api.data.brick")
.allowIfSubType("java.util.ArrayList")
.build()