question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot deserialize @JsonValue of type long in nested objects

See original GitHub issue

Using jackson-kotlin 2.9.3 the following test throws an Exception when deserializing:

data class Foo(
        @JsonValue
        val value: Long
)

data class Bar(
        val foo: Foo
)

@Test
fun name() {
    val om = ObjectMapper()
    om.registerModule(KotlinModule())
    val foo = Foo(4711L)
    val bar = Bar(foo)
    val asString = om.writeValueAsString(bar)
    println(asString)
    val fromString = om.readValue(asString, Bar::class.java)
    println(fromString)
}

The output is:

{“foo”:4711}

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `de.ottonow.contracts.CustomerIdTest$Foo` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (4711)
at [Source: (String)"{"foo":4711}"; line: 1, column: 8] (through reference chain: de.ottonow.contracts.CustomerIdTest$Bar["foo"])

at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1342)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1031)
at com.fasterxml.jackson.databind.deser.ValueInstantiator.createFromInt(ValueInstantiator.java:261)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromInt(StdValueInstantiator.java:347)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromNumber(BeanDeserializerBase.java:1302)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:172)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:519)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:527)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:416)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1265)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:325)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:3
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
apatridacommented, Oct 27, 2019

@BastianVoigt that is the correct workaround, this is because normally Jackson isn’t trying to find and infer a creator method automatically, and when the Jackson-Kotlin module does this, it sets the mode to DEFAULT which isn’t compatible with what you are trying.

The test case showing the workaround without creating a new creator method, but instead just annotate the class constructor is:


class Github120Test {
    data class Foo @JsonCreator(mode = JsonCreator.Mode.DELEGATING) constructor (
            @JsonValue
            val value: Long
    )

    data class Bar(
            val foo: Foo
    )

    @Test
    fun testNestedJsonValue() {
        val om = jacksonObjectMapper()
        val foo = Foo(4711L)
        val bar = Bar(foo)
        val asString = om.writeValueAsString(bar)
        assertEquals("{\"foo\":4711}", asString)

        val fromString = om.readValue(asString, Bar::class.java)
        assertEquals(bar, fromString)
    }
}
2reactions
BastianVoigtcommented, Jan 2, 2018

Workaround: add a static @JsonCreator factory which accepts Int or Number

companion object {
    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
    @JvmStatic
    fun createFrom(value: Number): CustomerId {
        return CustomerId(value.toLong())
    }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Mapping Nested Values with Jackson - Baeldung
Learn three ways to deserialize nested JSON values in Java using the ... we might want to parse a complex, densely nested object...
Read more >
Map nested json to a pojo with raw json value - Stack Overflow
Jackson is telling you that it can't insert an Object (in the error log) inside a String. The @JsonRawValue is used during serialization...
Read more >
Cannot deserialize the current json object because(e.g.{"name":"
object because(e.g.{" ; name":" ; into type because the type requires a json array (e.g.[1,2 ...
Read more >
Solve common issues with JSON in SQL Server
Return a nested JSON sub-object from JSON text with OPENJSON. Question. I can't open an array of complex JSON objects that contains both...
Read more >
How to use a JSON document, Utf8JsonReader, and ...
When you don't have a type to deserialize into. ... JsonValue`1[System.Text. ... Instead, search on nested JSON objects based on the known ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found