Skip to content
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

Exception when using @JsonIdentityInfo #194

Closed
MartinHaeusler opened this issue Nov 26, 2018 · 8 comments
Closed

Exception when using @JsonIdentityInfo #194

MartinHaeusler opened this issue Nov 26, 2018 · 8 comments
Assignees
Labels

Comments

@MartinHaeusler
Copy link

MartinHaeusler commented Nov 26, 2018

I'm trying to jsonize/de-jsonize a simple data object:

class MyStateObject(
    var id: String,
    var name: String? = null,
    var description: String? = null
)

Here's the test case:

    @Test
    fun dataClassJsonizationTest(){
        val mapper = jacksonObjectMapper()
        val json = mapper.writeValueAsString(MyStateObject("Hello"))
        val state = mapper.readValue<MyStateObject>(json)
        assertThat(state.id, `is`("Hello"))
    }

The test above works nicely, as expected. However, if I add an @JsonIdentityInfo to my data class, like so:

@JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator::class)
class MyStateObject(
    var id: String,
    var name: String? = null,
    var description: String? = null
)

... then the test case breaks with the following exception:

com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class org.example.MyStateObject] value failed for JSON property id due to missing (therefore NULL) value for creator parameter id which is a non-nullable type
 at [Source: (String)"{"id":"Hello","name":null,"description":null}"; line: 1, column: 45] (through reference chain: org.example.MyStateObject["id"])

	at com.fasterxml.jackson.module.kotlin.KotlinValueInstantiator.createFromObjectWith(KotlinValueInstantiator.kt:107)
	at com.fasterxml.jackson.databind.deser.impl.PropertyBasedCreator.build(PropertyBasedCreator.java:195)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:488)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1287)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithObjectId(BeanDeserializerBase.java:1257)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:157)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3023)

I really need to use @JsonIdentityInfo for my use case. I don't see what I might be doing wrong here, this is all standard Jackson business (at least in Java it is). It took me a good hour to find out what is even causing this exception.

Am I missing something / doing something wrong? Or might this be a bug in the Kotlin-Jackson library? Any workarounds?

@markuskreusch
Copy link

Had exactly the same problem.

Workaround I really do not understand why but when making the id field nullable it is working. The field is filled correctly. I am not sure why Jackson complains about a missing value when there actually is a value to be deserialized and deserialization works correct in the end.

Must be a bug? Anybody can have a look at this?

@sjtower
Copy link

sjtower commented Oct 11, 2019

+1 for this problem. Thank you @markuskreusch for the workaround, fixed my issue as well.
I'm not even using @JsonIdentityInfo, just a simple data class.

@masoncj
Copy link

masoncj commented Mar 18, 2021

We ran into this problem for quite a while. Here's a test case that demonstrates the problem, which is present in at least 2.10.5. Fortunately it seems like this has been fixed in recent versions (eg 2.11.4) and this test case is now passing!

class JsonIdentityInfoTest {
    val id = UUID.fromString("149800a6-7855-4e09-9185-02e442da8013")
    val json = """{"id": "$id", "name": "Foo"}"""

    @Test
    fun testIdentityInfo() {
        val mapper = jacksonObjectMapper()
        val value = mapper.readValue(json, WithIdentity::class.java)
        assertEquals(id, value.id)
        assertEquals(id.toString(), value.idString)
        assertEquals("Foo", value.name)
    }
}

@JsonIdentityInfo(
    property = "id",
    scope = WithIdentity::class,
    generator = ObjectIdGenerators.PropertyGenerator::class
)
class WithIdentity(val id: UUID = UUID.randomUUID(), val idString: String = id.toString(), val name: String)

@masoncj
Copy link

masoncj commented Mar 19, 2021

Apparently this is still broken in jackson-databind 2.11.2 and fixed in 2.11.4.

@dinomite
Copy link
Member

@masoncj Thanks for reporting the fix version. I'd like to add your test to our suite, would you fill it out and email a scan/photo of the result to info at fasterxml dot com?

https://github.com/FasterXML/jackson/blob/master/contributor-agreement.pdf

@dinomite dinomite self-assigned this Mar 19, 2021
@dinomite dinomite added the bug label Mar 19, 2021
@masoncj
Copy link

masoncj commented Mar 19, 2021

Signed and sent. Thanks @dinomite. Another interesting version of this test would remove the default arg on id (so no UUID.randomUUID()).

@cowtowncoder
Copy link
Member

CLA received, thanks!

dinomite added a commit that referenced this issue Mar 19, 2021
@dinomite
Copy link
Member

Added in 59c8d88 (and follow-up in 4dfa2d6)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants