FasterXML / FasterXML/jackson-module-scala

@JsonManagedReference doesn't work on Scala's collections

Abierto
#210 4 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
Scala
Estrellas
506
Forks
138
Merge medio
3 h 6 min
PR fusionados (30 d)
48

Descripción

Sample code snippet

``` scala
class Foo(val f:Int){
@JsonManagedReference val children: Seq[Bar] = null
}

class Bar(val b: Int) {
@JsonBackReference val parent: Foo = null
}
```

REPL:

``` scala
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
import org.Foo

val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
mapper.readValue( """{"f":1,"children":[{"b":2}]}""", classOf[Foo])
```

Exception occuried:

```
com.fasterxml.jackson.databind.JsonMappingException: Unsupported container type (scala.collection.immutable.$colon$colon) when resolving reference 'defaultReference' (through reference chain: org.Foo["children"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:210)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:177)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:1475)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:222)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:399)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1100)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:294)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:131)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3707)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2719)
... 35 elided
Caused by: java.lang.IllegalStateException: Unsupported container type (scala.collection.immutable.$colon$colon) when resolving reference 'defaultReference'
at com.fasterxml.jackson.databind.deser.impl.ManagedReferenceProperty.setAndReturn(ManagedReferenceProperty.java:135)
at com.fasterxml.jackson.databind.deser.impl.ManagedReferenceProperty.set(ManagedReferenceProperty.java:111)
at com.fasterxml.jackson.databind.deser.impl.ManagedReferenceProperty.deserializeAndSet(ManagedReferenceProperty.java:100)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:220)
... 41 more
```
### root cause

ManagedReferenceProperty.setAndReturn @ jackson-databind try to populate the parent instance to all its children but only cover the container types of Java Array, Collection and Map.

Since almost all the Scala collections have not implemented Java Collection or Map interface, like the Seq here in the sample, the exception thrown.

``` java
@Override
public Object setAndReturn(Object instance, Object value) throws IOException
{
/* 04-Feb-2014, tatu: As per [#390], it may be necessary to switch the
* ordering of forward/backward references, and start with back ref.
*/
if (value != null) {
if (_isContainer) { // ok, this gets ugly... but has to do for now
if (value instanceof Object[]) {
for (Object ob : (Object[]) value) {
if (ob != null) { _backProperty.set(ob, instance); }
}
} else if (value instanceof Collection) {
for (Object ob : (Collection) value) {
if (ob != null) { _backProperty.set(ob, instance); }
}
} else if (value instanceof Map) {
for (Object ob : ((Map) value).values()) {
if (ob != null) { _backProperty.set(ob, instance); }
}
} else {
throw new IllegalStateException("Unsupported container type ("+value.getClass().getName()
+") when resolving reference '"+_referenceName+"'");
}
} else {
_backProperty.set(value, instance);
}
}
// and then the forward reference itself
return _managedProperty.setAndReturn(instance, value);
}
```

In fact, I was wondering where should I raise this issue, to jackson-module-scala or jackson-databind ? I don't know but please allow me to paste it here firstly since you guys may be more familiar with Scala.

Anyway, hope that my analyze can help and the issue can be fixed by FasterXML in later release:)

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.