Search before asking

  • [x] I searched in the issues and found nothing similar.

When using Jackson ObjectMapper to convert Scala objects to Map[String, Any], numeric fields defined as BigInt are converted to Double instead of BigInteger or remaining as BigInt, causing precision loss.

This issue is not about regression across versions, but about undesired numeric coercion from a large integer to a Double.

We were using jackson 2.13.2 and in that Scala BigInt is converted to Long while deserializing at this line https://github.com/FasterXML/jackson-databind/blame/87014ed5f3dfc1dcc21b704c2ce117266780c166/src/main/java/com/fasterxml/jackson/databind/util/TokenBuffer.java#L1849

In Jackson 2.15.2, this has beed changed and the BigInt value is converted to Double type. The change is done here: https://github.com/FasterXML/jackson-databind/blame/74a57b2f6cd3b6e0fe2a61ed16734f15ba2abc95/src/main/java/com/fasterxml/jackson/databind/util/TokenBuffer.java#L1936

The serialisation part is same in both the version. But diff is while deserialisations. I wanted to understand if this is intentional or not? How can I fix this?

Version Information

2.15.2

Reproduction

case class A(b: BigInt = BigInt("9223372036854775808")) val obj = A() val map = objectMapper.convertValue(obj, classOf[Map[String, Any]]) println(map("b")) // 9.223372036854776E18 (Double) instead of BigInt or BigInteger

Expected behavior

BigInt in Scala should be treated a BigInteger in Java.

Additional context

No response

Comment From: pjfanning

If you use a generic map, you cannot expect us to guess that you want a BigInt. You can write a custom deserialize if you don't like the default behaviour.

Comment From: Saransh0905

The behaviour is changed from 2.13.2 to 2.15.2, which is a minor version change. That's why I thought it might be a bug. Can you provide a sample for custom deserialize and how to register it?

Comment From: pjfanning

https://www.baeldung.com/jackson-custom-serialization

You can also just take the map returned and write a function call the .intValue() on the double.

I would recommend that you use a strongly typed case class instead of using a Map as your target.

Comment From: Saransh0905

Thanks for the support @pjfanning.