-
-
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
Map deserialization results in different numeric classes based on json ordering (BigDecimal / Double) when used in combination with @JsonSubTypes #3133
Comments
Interesting. Due to ordering difference I suspect this is due to one ordering requiring buffering to handle polymorphism (that is, type id must be available before POJO values can be instantiated); and then there is the challenge of I agree that behavior should be identical; above is just talking through likely root cause that changes behavior between the cases. Thank you for including all the information to reproduce the issue! |
If you can give me a hint / entry point in the codebase i can try to fix / improve the logic and send a merge request. |
@mreiterer I wish there was an easy answer to that question, but handling of buffering is not exactly simple. Relevant code is in |
I did some debugging here and this seems to be related to #2644 When i look at the "_tokens" var in the segment of the TokenBuffer the value is already of type BigDecimal before the DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS is checked. The if in Vanilla.deserialize decides if getDecimalValue or getNumberValueis used, but this does not have any effect as the cast is already done. Mostly notes to myself for further investigation. The difference about the ordering seems to be located here: AsPropertyTypeDeserializer.deserializeTypedFromObject. If the typePropertyName is found first in the json structure: |
Correct: buffering is only used if absolutely required -- or put another way, if ordering happens to be optimal, buffering may be avoided, on assumption this is relatively common. |
@cowtowncoder Why is getNumberValueExact called in case of buffer copy, and not in the more common case (UntypedObjectDeserializer line 743 - jackson-databind 2.12.5) |
The difference is meant to defer possible truncation/coercion in case of buffering (since we have no idea what the target type is); whereas when using This matter more for binary formats where there is specific accurate representation, but is more problematic for textual formats that do not have distinction between various FP representations. And then there is the difference between streaming-level and databind-level configuration to consider too. Ideally, I think, the whole decoding should be deferred in buffering cases: parser would simply validate that the textual representation is valid JSON (or xml, yaml, csv etc) Number, but would not try to get Java |
Are there any plans to fix this issue in 2.14.x ? |
@mreiterer I don't think so due to timing constraints. |
Any news on this? Is there any workaround we can use in the meantime? |
@ellebrecht which Jackson version are you using? Seems like this issue has been fixed in later versions, at least in 2.15. Check out #4231. |
@ellebrecht As per @JooHyukKim 's comment if you have to see whether 2.16.0 still has the issue, that'd be helpful. And if anyone else has time to look into this that'd help. But as a general rule: if there is specific work towards fix for an issue, there will be comments here on this issue. |
As per #4231 has been fixed for at least 2.15.0, but will include as fixed in 2.15.4 and 2.16.0 release notes (no need to backdate older releases) |
We are using 2.15.3, the version pulled in by the current Spring Boot version 3.2.0. |
@ellebrecht please open a new issue - it is not a good idea to continue the conversation on on a closed issue. In the new issue, could you provide a new reproduction case? It appears #3133 works but you appear to have a case that is different from #3133. Please do not include any need to test with external dependencies like spring-boot. The new case should use plain Jackson code. |
Describe the bug
When deserializing a jsonSubTye which contains a map with numeric values (floats) the order of the json string results in different classes constructed.
I have pasted a complete Junit5 Test which can easily be used to reproduce the issue.
Version information
Happens from 2.12.0 onwards, in 2.11.x its ok.
To Reproduce
If you have a way to reproduce this with:
Expected behavior
Numeric values (point numbers) should always be created as Double unless stated otherwise with DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS
The text was updated successfully, but these errors were encountered: