-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Not able to deserialize Enum with default typing after upgrading 2.15.4 -> 2.17.1 #4849
Comments
Seems similar to the one I am working on ryt now FasterXML/jackson-modules-java8#335 |
I'm not sure the route cause is the same. In my case serializing Enum does not preceded it with a class name as a first array element ["TEST_ENUM_VALUE"] From some reason older version is able to read it. The newer one throws an error, expecting class name at index 0. As a proof if you proceed a serialized Enum with a class name at the index "0" it works perfectly fine: ["com.kze.test.TestClazz$TestEnum", "TEST_ENUM_VALUE"] [edit] |
There is |
Just as a note, using recommended in docs ObjectMapper mapper = new ObjectMapper();
PolymorphicTypeValidator polymorphicTypeValidator = BasicPolymorphicTypeValidator.builder()
.allowIfSubType("com.kze.test")
.allowIfSubType("java")
.build();
mapper.activateDefaultTypingAsProperty(polymorphicTypeValidator, EVERYTHING, "type");
mapper.registerModule(new JavaTimeModule()); |
Works fine with 2.16.0. I've checked 2.17.3 and it crashes exactly as the 2.17.1. |
While it probably makes no difference, testing should try the latest patch -- 2.18.2 -- to eliminate possibility of the issue being fixed. I don't think any change in-between versions would change behavior purposefully, but this is pretty complicated case so probably a side-effect of a fix. Now: difference between:
and
is that latter has no (polymorphic) type id, just And deserialization expects one or the other, depending on whether polymorphic handling is indicated. Due to default typing being enabled, presumably second structure should be serialized. It is also possible that the discrepancy between expecting inclusion (or not) of Type Id, via default Typing, differs between read- and writer-side due to Java Type Erasure -- serializing polymorphic root values, as is done here, is always riskier than serializing values referred indirectly (because in latter case full type information is available, unlike in root value case). |
I've tested it with the 2.18.2 and it's still not working. What I found out is the problematic bit is the EnumSet. If I replace it with regular Set it works perfectly fine with all the versions! EnumSet<TestEnum> input = EnumSet.of(TEST_ENUM_VALUE); to Set<TestEnum> input = Set.of(TEST_ENUM_VALUE); mapper is able to deserialize json, no exception is thrown and the output is:
So I guess it is rather rare case as it needs to have EnumSet with enum values serialized and deserialized with default typing enabled. Nevertheless there is a decadency between serializer (decides not to include type as a index 0) and deserializer which, in such case, requires type at the beginning of the array. [edit] ["java.util.EnumSet<com.kze.test.TestClazz$TestEnum>",["TEST_ENUM_VALUE"]] My assumption is that deserializer logic is too strict thus throwing Exception even if the type could be inferred from EnumSet |
@lenrok258 good analysis. Yes, not super common problem but definitely something that'd be good to fix.
|
@cowtowncoder Reading ["java.util.EnumSet<com.kze.test.TestClazz$TestEnum>",["TEST_ENUM_VALUE"] will always end up with an Exception (_com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (VALUE_STRING), expected START_ARRAY: _). I've tried to add @JsonTypeInfo @JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
public EnumSet<TestEnum> testEnumCollection = EnumSet.of(TEST_ENUM_VALUE); on the EnumSet property but with no luck. Seems like deserializer doesn't care and still expects array wrapper on the enum value itself (no only on an EnumSet). |
For urgent case, u may want tp update the varchar "j.u.EnumSet" to Set then modify code to deserialize into Set not EnumSet. |
Unformtunately as the json in db has the I think my only option is to write a migration code which takes all the values from the db and saves them again with EnumSet->Set migrated. |
Just to let you know, applying @JsonTypeInfo(use = NONE) on the enum declaration instead of on EnumSet property seems to be working fine. @JsonTypeInfo(use = NONE)
public enum TestEnum {
TEST_ENUM_VALUE
} Reading ["java.util.EnumSet<com.kze.test.TestClazz$TestEnum>",["TEST_ENUM_VALUE"] doesn't throw Exception in newer versions of Jackson so it could be treated as a good workaround for now. |
Search before asking
Describe the bug
After bumping up the version to 2.17.1 I'm not longer able to deserialize values serialized with the version 2.15.4.
Moreover, values serialized with the new version (2.17.1) give error when deserializing.
Version Information
2.17.1
Reproduction
Version 2.15.4 output
Version 2.17.1 error:
Expected behavior
Should be able to deserialized values
Additional context
No response
The text was updated successfully, but these errors were encountered: