jackson-databind icon indicating copy to clipboard operation
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`

Open ikamosi opened this issue 3 years ago • 1 comments

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?

ikamosi avatar Jun 21 '22 15:06 ikamosi

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().

cowtowncoder avatar Jun 21 '22 16:06 cowtowncoder

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

cowtowncoder avatar Jan 26 '23 03:01 cowtowncoder