On Mon, Oct 22, 2018 at 9:55 AM lev <[email protected]> wrote: > > I posted this question on SO, but it didn't get much attention, so I'm > posting here as well. > > ----- > > > I'd like to deserialize the following class: > > case class Target( > a: Option[Long], > b: String > ) > > while providing a custom initial value for missing fields. > > > I'm using this mixin to overcome this bug: > https://github.com/FasterXML/jackson-module-scala/wiki/FAQ#deserializing-optionint-and-other-primitive-challenges > > > trait Mixin { > @JsonDeserialize(contentAs = classOf[Long]) def a: Option[Long] > } > > > and I'm using this ValueInstantiator to provide a custom initial value: > > class TargetInstantiator extends ValueInstantiator{ > override def canCreateUsingDefault: Boolean = true > > override def createUsingDefault(ctxt: DeserializationContext): AnyRef = { > Target(Some(1), "bbb") > } > } > > > the mixing and the instantiator work well on their own, but when I combine > the 2 together, the mixin doesn't seem to have any effect > > > here is the full code: > > case class Target( > a: Option[Long], > b: String > ) > trait Mixin { > @JsonDeserialize(contentAs = classOf[Long]) def a: Option[Long] > } > > class TargetInstantiator extends ValueInstantiator{ > override def canCreateUsingDefault: Boolean = true > > override def createUsingDefault(ctxt: DeserializationContext): AnyRef = { > Target(Some(1), "bbb") > } > } > > > val svi = new SimpleValueInstantiators() > svi.addValueInstantiator(classOf[Target], new TargetInstantiator) > > val module = new SimpleModule("MyModule") > module.setValueInstantiators(svi) > > val mapper = new ObjectMapper() > .registerModule(DefaultScalaModule) > .registerModule(module) > .addMixIn(classOf[Target], classOf[Mixin]) > val req = > """{ > | "a": 123 > |} > """.stripMargin > val res = mapper.readValue(req, classOf[Target]) > println(res.a.map(_ + 1)) //should print Some(124) > println(res.b) //should print "bbb" > > the above code would fail with the error > > java.lang.Integer cannot be cast to java.lang.Long > > on the first print. > > > if I comment out .registerModule(module), and add "b" to the json string, the > code would work. > > > Is it possible to make the mixin and the instantiator work together?
At high level, yes, mix-ins and ValueInstantiator can and should be able to co-exist. But I guess question is more about ValueInstantiator and `contentAs` annotation via mix-ins. Use of mix-ins, in itself, is invisible to most code in Jackson and would be behave same as if annotation was directly used in target class. Challenge here is mostly, I think, that this is for Scala, and Scala module is both lagging behind with some features (partly since I don't know Scala enough to help much with the module) and also uses some of the facilities to support Scala features. I don't know for sure but it might actually use ValueInstantiators of its own. So one thing that is often done to troubleshoot is to see if there is Java-only reproduction of the issue; if so, it can be worked on jackson-databind. If not, it is likely problem with Scala module's handling of things. -+ Tatu +- -- You received this message because you are subscribed to the Google Groups "jackson-user" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
