Skip to content

Cannot deserialize value class #532

Closed
@pvorb

Description

@pvorb

Describe the bug
I have the following classes:

data class RequestDto(
    val assetIds: List<AssetId>
)

@JvmInline
value class AssetId(
    val id: Int
)

and I want to deserialize those requests like follows

val objectMapper = ObjectMapper().registerKotlinModule()

val request = objectMapper.readValue("""{"assetIds": [1, 2, 3]}""", RequestDto::class.java)

But this fails and causes the following exception:

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.deviceinsight.ms.maintenancemanager.main.model.AssetId` (no Creators, like default constructor, exist): no int/Int-argument constructor/factory method to deserialize from Number value (1)
 at [Source: (String)"{"assetIds": [1, 2, 3]}"; line: 1, column: 15] (through reference chain: RequestDto["assetIds"]->java.util.ArrayList[0])
	at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
	at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1904)
	at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)
	at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1349)
	at com.fasterxml.jackson.databind.deser.ValueInstantiator.createFromInt(ValueInstantiator.java:324)
	at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromInt(StdValueInstantiator.java:376)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromNumber(BeanDeserializerBase.java:1442)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:198)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:186)
	at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:355)
...

To Reproduce
Just paste the snippets from above in a Kotlin file, wrap the last statement in a fun main() and add the libraries with below versions on the classpath.

Expected behavior
I would've expected this piece of code to work and parse the JSON to:

val request = RequestDto(assetIds = listOf(AssetId(1), AssetId(2), AssetId(3)))

Versions
Kotlin: 1.6.10
Jackson-module-kotlin: 2.13.1
Jackson-databind: 2.13.1

Additional context
Serializing the RequestDto correctly leads to the following JSON:

{"assetIds":[1,2,3]}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions