jackson-databind: One field deserialization bug
Search before asking
- I searched in the issues and found nothing similar.
Describe the bug
I compile java sources with -parameters
and I register Jackson’s com.fasterxml.jackson.module:jackson-module-parameter-names:2.16.0
Everything works as expected for classes with two and/or more fields.
But deserialization of a class with one field — fails.
Adding any of annotations:
@ConstructorProperties("a")
or
@JsonCreator
helps.
But they are not required in case of “2+ field” classes.
A very short test that shows the problem is attached.
Version Information
2.16.0
Reproduction
public class JacksonBehaviorTest {
public static class One {
public final Integer a;
//@ConstructorProperties("a")
//@JsonCreator
public One (Integer a){ this.a = a; }
}
public static class Two {
public final Integer a;
public final Integer b;
public Two (Integer a, Integer b){ this.a = a; this.b = b; }
}
@Test
void testDeserializationBug () throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper().findAndRegisterModules();
String s = "{\"b\":2,\"a\":1}";// wrong order to show `-parameters` works
Two two = mapper.readValue(s, Two.class);
assertEquals("{\"a\":1,\"b\":2}", mapper.writeValueAsString(two));// Two is ok
s = "{\"a\":1}";
mapper.readValue(s, One.class);
fail("One must fail with: MismatchedInputException: Cannot construct instance of `test.JacksonBehaviorTest$One` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator) ");
}
}
Expected behavior
Deserialization must work for class One as it does for class Two
Additional context
Funny fact
@ConstructorProperties
with ANY text helps:
E.g.
@ConstructorProperties("You can call me Your Majesty")
works and one.a == 1
About this issue
- Original URL
- State: closed
- Created 7 months ago
- Reactions: 3
- Comments: 16 (9 by maintainers)
Maybe it is time to add ~
com.fasterxml.jackson.databind.MapperFeature#SUPPORT_ONE_ARG_CTOR
if a class has one ctor with one parameter, and the type of this parameter is the same as one final field, and this MapperFeature is enabled then use this ctor even withoutjavac -parameters
andjackson-module-parameter-names
🤷♀️this is documented behavior, see the readme https://github.com/FasterXML/jackson-modules-java8/tree/2.17/parameter-names
I think it’s more like there’s no feature request because whatever that is already available is enough to make things work.
And making such change may break behaviour people are already relying on (I’ve learned my lesson from my previous contribution that users do really weird things).
The problem is currently, Jackson considers a constructor argument as “having implicit name” if and only if the constructor is annotated with
@JsonCreator
or@ConstructorProperties
, which is why it worked when you used them.Reminds me of
ConstructorDetector.USE_PROPERTIES_BASED
https://cowtowncoder.medium.com/jackson-2-12-most-wanted-3-5-246624e2d3d0 - is that what you’re looking for?ConstructorProperties is a bit weird, i’m guessing it might just work as a JsonCreator and then the parameters module overrides the param names