Reputation: 1045
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
firstProperty
is missing, it should throw an exception. firstProperty
is null, it should assign null since it is nullable. secondProperty
is missing or null it should assign the default value of 1234
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
Upvotes: 2
Views: 4059
Reputation: 17066
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
Upvotes: 2
Reputation: 29844
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
@get
and @param
annotations. @JsonProperty
alone is sufficient for your use-case.Upvotes: 1