2

Using Jackson 2.9.6

I have the following data class definition:

data class SomeDTO @JsonCreator internal constructor
(
    @get:JsonProperty(value = "first-property", required = true)
    @param:JsonProperty(value = "first-property", required = true)
    val firstProperty: Long?,

    @get:JsonProperty(value = "second-property")
    @param:JsonProperty(value = "second-property")
    val secondProperty: Int = 1234

    @get:JsonProperty("third-property", required = true)
    @param:JsonProperty("third-property", required = true)
    val thirdProperty: Int
)

What I expect for a JSON that deserializes into SomeDTO

  1. If firstProperty is missing, it should throw an exception.
  2. If firstProperty is null, it should assign null since it is nullable.
  3. If secondProperty is missing or null it should assign the default value of 1234
  4. If thirdProperty is missing or null, it should throw an exception.

Basically that I can control which values can be deserialized and into what.

What I am experiencing:

If not using KotlinModule then (1), (2), and (4) work but (3) fails with:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot map null into type int (set DeserializationConfig.DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES to 'false' to allow)

If using KotlinModule then (2), (3), and (4) work but (1) fails.

Main part of ObjectMapper configuration:

disable(
        MapperFeature.AUTO_DETECT_CREATORS,
        MapperFeature.AUTO_DETECT_FIELDS,
        MapperFeature.AUTO_DETECT_GETTERS,
        MapperFeature.AUTO_DETECT_IS_GETTERS
       )
disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)

registerModule(ParanamerModule())
registerModule(KotlinModule()) // Might be registered or not

disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)

I think it is easier to use the KotlinModule but I don't know how to tell it to not auto assign null values to nullable fields when the property is missing in the JSON

4
  • 1
    Have you tried @field in place of @get or @param? Commented Oct 3, 2018 at 16:44
  • 1
    @jaco0646 Yes I have, and didn't work. If I am not mistaken that shouldn't work anyways since I need to annotate the constructor parameters foremost Commented Oct 3, 2018 at 18:10
  • 1
    You're right. I missed the @JsonCreator annotation. Commented Oct 3, 2018 at 19:32
  • 1
    Try updating to version 2.9.7. There is a bug fix (#168) that may address the issue you are seeing in the Kotlin module. Commented Oct 3, 2018 at 19:34

2 Answers 2

2

Updating the Kotlin module to version 2.9.7 produces an exception when firstProperty is missing. I've tested it repeatedly, going back and forth between 2.9.6 and 2.9.7 with the code and configuration copied from the OP.

A bug fix in 2.9.7 matches the unexpected behavior described in the OP.

Fixes #168 where JsonProperty(required=true) was being ignored and overridden by nullability check

https://github.com/FasterXML/jackson-module-kotlin/issues/168

Sign up to request clarification or add additional context in comments.

1 Comment

Weird... I tried it yesterday and didn't work. I will try again then!
1

This should do what you want:

data class SomeDTO(
        @JsonProperty(value = "first-property", required = true)
        val firstProperty: Long?,

        @JsonProperty(value = "second-property")
        val secondProperty: Int = 1234,

        @JsonProperty("third-property", required = true)
        val thirdProperty: Int
)

A few notes:

1. Since you are using the primary constructor for your annotated fields, in Kotlin you don't need the @JsonCreator annotation.

This is what the GitHub page of the Jackson project says:

By default, Jackson tries to use the "default" constructor (one that takes no arguments), when creating value instances. But you can also choose to use another constructor, or a static factory method to create instance. To do this, you will need to use annotation @JsonCreator, and possibly @JsonProperty annotations to bind names to arguments

  1. You dont need the separate @get and @param annotations. @JsonProperty alone is sufficient for your use-case.

3 Comments

Even though what you proposed saved me some redundant code it still didn't solve my problem while using the KotlinModule
Expectation (1) when using the KotlinModule is not throwing an exception
@IS1_SO even if the value is required, if you make it nullable that's the default value in case it is missing.. I don't think you can explicitely require it, when it is nullable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.