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

Mutator inference during deserialization doesn't work for Kotlin (data) objects #824

Open
3 tasks done
hudson155 opened this issue Aug 4, 2024 · 2 comments
Open
3 tasks done
Labels

Comments

@hudson155
Copy link

Search before asking

  • I searched in the issues and found nothing similar.
  • I searched in the issues of databind and other modules used and found nothing similar.
  • I have confirmed that the problem only occurs when using Kotlin.

Describe the bug

If I have a data class with a property defined in the body, deserializing works fine.

If I have a data object with a property defined in the body, deserializing throws an exception when deserializing due to an unrecognized field.

Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "int" (class Second), not marked as ignorable (0 known properties: ])

I think this works fine for classes due to MapperFeature.ALLOW_FINAL_FIELDS_AS_MUTATORS and MapperFeature.INFER_PROPERTY_MUTATORS (both default to true), but with Kotlin objects it doesn't work.

To Reproduce

data class First(
  val foo: String,
) {
  val int: Int = 1
}

data object Second {
  val int: Int = 2
}

fun main() {
  val mapper = jacksonObjectMapper()
  println(mapper.writeValueAsString(First("bar"))) // {"foo":"bar","int":1}
  println(mapper.writeValueAsString(Second)) // {"int":2}
  println(mapper.readValue<First>("{\"foo\":\"bar\",\"int\":1}")) // First(foo=bar)
  println(mapper.readValue<Second>("{\"int\":2}")) // THROWS!
}

Expected behavior

I expect no exception to be thrown in the above example.

Versions

Kotlin: 2.0.0
Jackson-module-kotlin: 2.17.2
Jackson-databind: 2.17.2

Additional context

No response

@hudson155 hudson155 added the bug label Aug 4, 2024
@hudson155
Copy link
Author

I just verified that this issue also exists when using Kotlin 1.9.25.

@k163377
Copy link
Contributor

k163377 commented Sep 14, 2024

@hudson155
Sorry for the delay in replying.

I have checked and this appears to be normal behavior for Jackson.
When deserializing a class, if an unrequested property exists on JSON, it fails by default.
Enabling FAIL_ON_UNKNOWN_PROPERTIES will suppress this problem.
https://javadoc.io/doc/com.fasterxml.jackson.core/jackson-databind/latest/com/fasterxml/jackson/databind/DeserializationFeature.html#FAIL_ON_UNKNOWN_PROPERTIES

package com.fasterxml.jackson.module.kotlin

import com.fasterxml.jackson.databind.DeserializationFeature

data object Second {
    val int: Int = 2
}

fun main() {
    val mapper = jacksonObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
    println(mapper.readValue<Second>("{\"int\":2}")) // -> Second
}

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

2 participants