jackson-databind
jackson-databind copied to clipboard
activateDefaultTyping and JsonDeserialize(converter do not work on Date fields
Describe the bug
When using objectMapper.activateDefaultTyping
and @JsonDeserialize(converter = ...)
on a Date field, Jackson perhaps incorrectly serializes a Long as ["java.lang.Long",1234567890000]
(I would have expected 1234567890000
), and throws an exception instead of deserializing.
Throws:
com.fasterxml.jackson.databind.exc.MismatchedInputException:
Cannot deserialize value of type `java.lang.Long` from Array value (token `JsonToken.START_ARRAY`)
at [Source: (String)"{"@class":"com.example.jacksonbug.DateReference","date":["java.lang.Long",1666213651605]}";
line: 1, column: 57] (through reference chain: com.example.jacksonbug.DateReference["date"])
However, the same bug does not appear with other types.
If I put a @JsonDeserialize(converter = ...)
on a custom type, jackson serializes/deserializes correctly.
I've included a repo to reproduce both scenarios.
Version information Discovered in jackson-databind 2.13.4 Also reproducible in jackson-databind 2.14.0-rc2
To Reproduce Run the main method here: https://github.com/craftmaster2190/jackson-date-converter-bug
Ok, first things first: the reason why long
/ Long
handling differs from other types is due to "long" being one of a small number of "natural" types, for which type information is never to be included (as an optimization -- in hindsight, possibly not a good idea). Other natural types are String
, boolean
/Boolean
, double
/Double
.
But in this case use of Converter
is probably problematic: if the nominal/declared type is Date
there is probably discrepancy between handling somewhere (for Long
no type id can/should be written/expected to read; for Date
type id should be written and read).
At any rate, handling is wrong; it should either:
- Handle values as
Long
, no type id written nor expected; or - Handle values as
Date
, use type id
I think latter would be the correct behavior. But fundamentally use of Converters is challenging with Polymorphic Typing since the idea is that there is this "intermediate" convenience type and then routing of calls for TypeSerializer
/JsonSerializer
and TypeDeserializer
/JsonDeserializer
(first of pair handling Type Id, second actual value once type is written/read) needs to translate calls in proper way.
So while it'd be good to fix this, I would also recommend considering this combination of features problematic and if possible finding another way to achieve the same result: possibly custom serializer (and likely deserializer) instead of converter-based one.
I hope to look into this deeper in future, but thought I'd add a note now (I have 2.14 release tasks to focus on but going through all issue reports as well).