aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release-notes/VERSION1
-rw-r--r--src/main/java/com/fasterxml/jackson/databind/deser/AbstractDeserializer.java22
-rw-r--r--src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java4
-rw-r--r--src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBuilder.java2
-rw-r--r--src/test/java/com/fasterxml/jackson/failing/TestAbstractParentChild.java67
5 files changed, 22 insertions, 74 deletions
diff --git a/release-notes/VERSION b/release-notes/VERSION
index 8f1281f13..f81637eca 100644
--- a/release-notes/VERSION
+++ b/release-notes/VERSION
@@ -8,6 +8,7 @@ Description:
Fixes:
+* [JACKSON-368]: Problems with managed references, abstract types
* [JACKSON-711]: Delegating @JsonCreator did not work with Injectable values
* [JACKSON-798]: Problem with external type id, creators
(reported by Casey L)
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/AbstractDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/AbstractDeserializer.java
index 17ef72762..b663b8069 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/AbstractDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/AbstractDeserializer.java
@@ -1,6 +1,7 @@
package com.fasterxml.jackson.databind.deser;
import java.io.IOException;
+import java.util.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
@@ -22,6 +23,8 @@ public class AbstractDeserializer
protected final JavaType _baseType;
protected final ObjectIdReader _objectIdReader;
+
+ protected final Map<String, SettableBeanProperty> _backRefProperties;
// support for "native" types, which require special care:
@@ -30,11 +33,13 @@ public class AbstractDeserializer
protected final boolean _acceptInt;
protected final boolean _acceptDouble;
- public AbstractDeserializer(JavaType bt, ObjectIdReader oir)
+ public AbstractDeserializer(BeanDeserializerBuilder builder,
+ BeanDescription beanDesc, Map<String, SettableBeanProperty> backRefProps)
{
- _baseType = bt;
- _objectIdReader = oir;
- Class<?> cls = bt.getRawClass();
+ _baseType = beanDesc.getType();
+ _objectIdReader = builder.getObjectIdReader();
+ _backRefProperties = backRefProps;
+ Class<?> cls = _baseType.getRawClass();
_acceptString = cls.isAssignableFrom(String.class);
_acceptBoolean = (cls == Boolean.TYPE) || cls.isAssignableFrom(Boolean.class);
_acceptInt = (cls == Integer.TYPE) || cls.isAssignableFrom(Integer.class);
@@ -60,6 +65,15 @@ public class AbstractDeserializer
return _objectIdReader;
}
+ /**
+ * Method called by <code>BeanDeserializer</code> to resolve back reference
+ * part of managed references.
+ */
+ public SettableBeanProperty findBackReference(String logicalName)
+ {
+ return (_backRefProperties == null) ? null : _backRefProperties.get(logicalName);
+ }
+
/*
/**********************************************************
/* Deserializer implementation
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
index 937124686..7ef28e30c 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java
@@ -559,8 +559,8 @@ public abstract class BeanDeserializerBase
}
backProp = ((BeanDeserializerBase) contentDeser).findBackReference(refName);
isContainer = true;
- } else if (valueDeser instanceof AbstractDeserializer) { // [JACKSON-368]: not easy to fix, alas
- throw new IllegalArgumentException("Can not handle managed/back reference for abstract types (property "+_beanType.getRawClass().getName()+"."+prop.getName()+")");
+ } else if (valueDeser instanceof AbstractDeserializer) {
+ backProp = ((AbstractDeserializer) valueDeser).findBackReference(refName);
} else {
throw new IllegalArgumentException("Can not handle managed/back reference '"+refName
+"': type for value deserializer is not BeanDeserializer or ContainerDeserializerBase, but "
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBuilder.java b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBuilder.java
index 7366cae95..f794e46b9 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBuilder.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBuilder.java
@@ -342,7 +342,7 @@ public class BeanDeserializerBuilder
*/
public AbstractDeserializer buildAbstract()
{
- return new AbstractDeserializer(_beanDesc.getType(), _objectIdReader);
+ return new AbstractDeserializer(this, _beanDesc, _backRefProperties);
}
/**
diff --git a/src/test/java/com/fasterxml/jackson/failing/TestAbstractParentChild.java b/src/test/java/com/fasterxml/jackson/failing/TestAbstractParentChild.java
deleted file mode 100644
index ec4daa331..000000000
--- a/src/test/java/com/fasterxml/jackson/failing/TestAbstractParentChild.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.fasterxml.jackson.failing;
-
-
-import com.fasterxml.jackson.annotation.*;
-import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
-import com.fasterxml.jackson.databind.BaseMapTest;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-/**
- * Currently (1.8) parent/child dependencies do not work in
- * combination with abstract types; they should, but fixing this
- * require major changes to handling of both features.
- */
-public class TestAbstractParentChild extends BaseMapTest
-{
- @JsonTypeInfo(use=Id.NAME)
- @JsonSubTypes({@JsonSubTypes.Type(ConcreteNode.class)})
- static abstract class AbstractNode
- {
- public String id;
-
- @JsonManagedReference public AbstractNode next;
- @JsonBackReference public AbstractNode prev;
- }
-
- @JsonTypeName("concrete")
- static class ConcreteNode extends AbstractNode {
- public ConcreteNode() { }
- public ConcreteNode(String id) { this.id = id; }
- }
-
- /*
- /**********************************************************
- /* Unit tests
- /**********************************************************
- */
-
- /* 22-Sep-2010, tatu: This is for [JACKSON-368]. Easy to reproduce the issue,
- * but alas not nearly as easy to resolve. Problem is that AbstractDeserializer
- * has little knowledge of actual type, and so linkage can not be made statically.
- */
- public void testAbstract() throws Exception
- {
- AbstractNode parent = new ConcreteNode("p");
- AbstractNode child = new ConcreteNode("c");
- parent.next = child;
- child.prev = parent;
-
- // serialization ought to be ok
- ObjectMapper mapper = new ObjectMapper();
- String json = mapper.writeValueAsString(parent);
-
- AbstractNode root = null;
- try {
- root = mapper.readValue(json, AbstractNode.class);
- } catch (IllegalArgumentException e) {
- fail("Did not expect an exception; got: "+e.getMessage());
- }
- assertEquals(ConcreteNode.class, root.getClass());
- assertEquals("p", root.id);
- assertNull(root.prev);
- AbstractNode leaf = root.next;
- assertNotNull(leaf);
- assertEquals("c", leaf.id);
- assertSame(parent, leaf.prev);
- }
-}