diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java
index 3a95d20fe8..b9373cdc5e 100644
--- a/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java
+++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java
@@ -189,8 +189,9 @@ public enum DeserializationFeature implements ConfigFeature
/**
* Feature that determines what happens if an Object Id reference is encountered
* that does not refer to an actual Object with that id ("unresolved Object Id"):
- * either an exception is thrown (true), or a null object is used
- * instead (false).
+ * either an exception {@link com.fasterxml.jackson.databind.deser.UnresolvedForwardReference}
+ * containing information about {@link com.fasterxml.jackson.databind.deser.UnresolvedId}
+ * is thrown (true), or a null object is used instead (false).
* Note that if this is set to false, no further processing is done;
* specifically, if reference is defined via setter method, that method will NOT
* be called.
diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java
index bc213b734b..9f6e895c20 100644
--- a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java
+++ b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java
@@ -182,6 +182,26 @@ public ObjectIdResolver newForDeserialization(Object c)
}
}
+ static class SomeWrapper {
+ @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id")
+ public SomeNode node;
+
+ public SomeWrapper() {}
+
+ public SomeWrapper(int v) {
+ node = new SomeNode(v);
+ }
+ }
+
+ static class SomeNode {
+ public int value;
+ public SomeWrapper next;
+
+ public SomeNode() {this(0);}
+
+ public SomeNode(int v) {value = v;}
+ }
+
/*
/*****************************************************
/* Unit tests, external id deserialization
@@ -466,4 +486,60 @@ public void testNullObjectId() throws Exception
assertNotNull(value);
assertEquals(3, value.value);
}
+
+ /*
+ /*****************************************************
+ /* Unit tests in conjunction with DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS
+ /*****************************************************
+ */
+
+
+ private final ObjectMapper DEFAULT_MAPPER = newJsonMapper();
+
+ private final ObjectMapper DISABLED_MAPPER = newJsonMapper()
+ .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, false);
+
+ private final ObjectMapper ENABLED_MAPPER = newJsonMapper()
+ .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, true);
+
+ public void testDefaultSetting() {
+ assertTrue(DEFAULT_MAPPER.isEnabled(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS));
+ assertTrue(ENABLED_MAPPER.isEnabled(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS));
+ assertFalse(DISABLED_MAPPER.isEnabled(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS));
+ }
+
+ public void testSuccessResolvedObjectIds() throws Exception {
+ String json = a2q("{'node':{'@id':1,'value':7,'next':{'node':1}}}");
+
+ SomeWrapper wrapper = DEFAULT_MAPPER.readValue(json, SomeWrapper.class);
+
+ assertSame(wrapper.node, wrapper.node.next.node);
+ assertSame(wrapper.node.next.node, wrapper.node.next.node.next.node);
+ }
+
+ public void testUnresolvedObjectIdsFailure() throws Exception {
+ // Set-up : node id of 2 that doesn't exist,
+ String json = a2q("{'node':{'@id':1,'value':7,'next':{'node':2}}}");
+
+ // 1. Does not fail, because disabled such.
+ SomeWrapper wrapper = DISABLED_MAPPER.readValue(json, SomeWrapper.class);
+ assertNull(wrapper.node.next.node);
+
+ try {
+ // 2. Will fail by default.
+ DEFAULT_MAPPER.readValue(json, SomeWrapper.class);
+ fail("should not pass");
+ } catch (UnresolvedForwardReference e) {
+ verifyException(e, "Unresolved forward reference", "Object id [2]");
+ }
+
+ try {
+ // 3. Will also throw exception, because configured as such.
+ ENABLED_MAPPER.readValue(json, SomeWrapper.class);
+ fail("should not pass");
+ } catch (UnresolvedForwardReference e) {
+ verifyException(e, "Unresolved forward reference", "Object id [2]");
+ }
+ }
+
}