jackson-databind
jackson-databind copied to clipboard
If deduction-based polymorphism is used, Jackson will deserialize all decimal values as BigDecimal if they are mapped to `java.lang.Object`
Describe the bug
If deduction-based polymorphism is used, Jackson will deserialize all decimal values as BigDecimal if they are mapped to java.lang.Object.
Version information 2.13.3
To Reproduce
This can be reproduced by running the following tests:
class DeductionTest {
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
@JsonSubTypes({ @JsonSubTypes.Type(Sub.class)})
private static class Super { }
private static class Sub extends Super {
private Object value;
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
@Test
void deserializeDecimal() throws IOException {
String json = "{\"value\": 1.0}";
ObjectMapper mapper = new ObjectMapper();
Sub sub = (Sub)mapper.readValue(json, Super.class);
System.out.println("deserializeDecimal: " + sub.getValue().getClass());
}
@Test
void deserializeInteger() throws IOException {
String json = "{\"value\": 1}";
ObjectMapper mapper = new ObjectMapper();
Sub sub = (Sub)mapper.readValue(json, Super.class);
System.out.println("deserializeInteger: " + sub.getValue().getClass());
}
}
Prints out:
deserializeDecimal: class java.math.BigDecimal
deserializeInteger: class java.lang.Integer
I believe the first one should be deserialized as java.lang.Double instead of java.math.BigDecimal?
Hmmh. You are probably right, wrt expected default mapping. Not sure if this is related to deduction-based polymorphic handling (could be same for other polymorphic methods).
As a work-around it probably makes sense to cast value as Number (if known it should be), call Number.asDouble().
NOTE: almost certainly related to buffering of tokens, needed often with polymorphic deserialization.
Interesting that result is BigDecimal, nonetheless; should produce Double unless ObjectMapper configured with DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS