Closed uthornbl closed 11 years ago
This is explained in the FAQ:
The Scala module has informed Jackson that
Option
is effectively a container type, but it relies on Java reflection to determined the contained type, and comes up withObject
. Jackson has rules for dealing with this situation, which dictate that the dynamic type ofObject
values should be the closest natural Java type for the value:java.lang.String
for strings,java.lang.Integer
,java.lang.Long
, orjava.math.BigInteger
for whole numbers, depending on what size the number fits into
The workaround for now is to use @JsonDeserialize(contentAs = classOf[java.lang.Long])
to tell Jackson to widen small integers to longs.
Resolving in favor of #104 which tracks the root cause of this issue.
You should use Scala reflection to extract the correct type parameter of Option. I succeeded to do it in my extension to Spring conversion service. If you need my help, I'll provide a clue.
In an ideal world, this would be the way I would do it. However, Scala reflection in 2.10 has a bug that I was unable to work around when I first looked at it. #44 had the relevant changes, and I had integrated them into a branch, but at the time of 2.10.0-RC2, the tests were crashing.
The relevant bug is SI-6548, which is fixed, but due to binary compatibility restrictions cannot be released until Scala 2.11. Thus reflection is useless to me in 2.10.
Even if Scala reflection worked perfectly in 2.10, there's still the problem of 2.9 support which I have not yet decided to abandon. The current road map is to implement an approach based on parsing @ScalaSignature
, which is pending development of a library to do that, which doesn't depend on the scala compiler itself (as most scalap-based signature parsing tools do). That work is still in progress.
Unfortunately, there are lots of issues in 2.10 reflection. I encountered another one causing sporadic exceptions on multi-threaded calls to the reflection API. The only workaround was to synchronize all such calls globally.
When decoding a string into e.g. a case class with attributes of type Option[Long] it seems to work (no errors). However, when I later try to access the field and assign it to a Long val a cast error is thrown revealing that a Java Integer has been stored instead of a Long: ClassCastException: java.lang.Integer cannot be cast to java.lang.Long. Possible work-arounds are a) wrapping the Option[Long] making it a Long member of a case class and then use the case class as an Option or b) Use a Long and consider the value 0 as absence of input (this assumes you don't expect 0s from the source...) or c) Do the casting yourself when you access the field, e.g. myField.get.toString.toLong. Could the library be made to handle the decode properly?