jackson-module-scala
jackson-module-scala copied to clipboard
Cannot serialize option of anyval in a collection
I have a sample test here:
"Anyvals" should "serialize json" in {
val groups = (0 until 10).map(_ =>
AnyHolder(
Some(TestAny("data"))
))
val objectMapper = new ObjectMapper().registerModule(DefaultScalaModule)
println(objectMapper.writeValueAsString(data))
}
}
case class AnyHolder(
testAny: Option[TestAny]
)
case class TestAny(data: String) extends AnyVal
This fails with
tests.TestAny cannot be cast to java.lang.String (through reference chain: scala.collection.convert.IterableWrapper[0]->tests.AnyHolder["testAny"])
com.fasterxml.jackson.databind.JsonMappingException: tests.TestAny cannot be cast to java.lang.String (through reference chain: scala.collection.convert.IterableWrapper[0]->tests.AnyHolder["testAny"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:378)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:338)
at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:342)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:686)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:157)
at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:149)
at com.fasterxml.jackson.module.scala.ser.IterableSerializer$class.serializeContents(IterableSerializerModule.scala:28)
at com.fasterxml.jackson.module.scala.ser.UnresolvedIterableSerializer.serializeContents(IterableSerializerModule.scala:56)
Using jackson-core 2.7.4, jackson-databind 2.7.4, jackson-scala-module 2.7.4
Are there any workarounds to get this to work?
As a temporary workaround I disabled anyval support in my application and to get the json to be over the wire the same I added the @(JsonValue @getter) annotation to the wrapped field.
Having the same issue, is there is work around?
@Assarin I in general moved off of anyval support for all my scala stuff. It was too problematic. I instead created this https://github.com/paradoxical-io/scala-global/tree/master/jackson/src/main/scala/io/paradoxical/jackson which is custom jackson module that knows how to serialize and deserialize tagged types using a trait:
https://github.com/paradoxical-io/scala-global/blob/master/global/src/main/scala/io/paradoxical/global/tiny/Tiny.scala
which i use like this:
https://github.com/paradoxical-io/scala-global/blob/master/jackson/src/test/scala/io/paradoxical/jackson/TinyTests.scala
I found this to be easier to give me the NewType support but still play nice with serialization/swagger/reflection/etc.
These jars are available on maven central if you are interested
@Assarin yet another option is to use jsoniter-scala - it has support of AnyVals with any combination of Scala collection and other types. Also it is much safe and efficient than other options.