Fix #1607
diff --git a/release-notes/VERSION b/release-notes/VERSION
index 93869e2..2347008 100644
--- a/release-notes/VERSION
+++ b/release-notes/VERSION
@@ -4,6 +4,11 @@
=== Releases ===
------------------------------------------------------------------------
+2.7.9.2 (not yet released)
+
+#1607: @JsonIdentityReference not used when setup on class only
+ (reported by vboulaye@github)
+
2.7.9.1 (18-Apr-2017)
#1599: Jackson Deserializer security vulnerability
diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java b/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java
index d74a2e9..f2bc1ca 100644
--- a/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java
+++ b/src/main/java/com/fasterxml/jackson/databind/introspect/JacksonAnnotationIntrospector.java
@@ -576,10 +576,13 @@
@Override
public ObjectIdInfo findObjectReferenceInfo(Annotated ann, ObjectIdInfo objectIdInfo) {
JsonIdentityReference ref = _findAnnotation(ann, JsonIdentityReference.class);
- if (ref != null) {
- objectIdInfo = objectIdInfo.withAlwaysAsId(ref.alwaysAsId());
+ if (ref == null) {
+ return objectIdInfo;
}
- return objectIdInfo;
+ if (objectIdInfo == null) {
+ objectIdInfo = ObjectIdInfo.empty();
+ }
+ return objectIdInfo.withAlwaysAsId(ref.alwaysAsId());
}
/*
diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/ObjectIdInfo.java b/src/main/java/com/fasterxml/jackson/databind/introspect/ObjectIdInfo.java
index 0457ec0..049ab35 100644
--- a/src/main/java/com/fasterxml/jackson/databind/introspect/ObjectIdInfo.java
+++ b/src/main/java/com/fasterxml/jackson/databind/introspect/ObjectIdInfo.java
@@ -19,6 +19,11 @@
protected final Class<?> _scope;
protected final boolean _alwaysAsId;
+ /**
+ * @since 2.8.9
+ */
+ private final static ObjectIdInfo EMPTY = new ObjectIdInfo(PropertyName.NO_NAME, Object.class, null, false, null);
+
public ObjectIdInfo(PropertyName name, Class<?> scope, Class<? extends ObjectIdGenerator<?>> gen,
Class<? extends ObjectIdResolver> resolver)
{
@@ -56,6 +61,10 @@
_resolver = resolver;
}
+ public static ObjectIdInfo empty() {
+ return EMPTY;
+ }
+
public ObjectIdInfo withAlwaysAsId(boolean state) {
if (_alwaysAsId == state) {
return this;
diff --git a/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java b/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java
index 658786d..3b838cc 100644
--- a/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java
+++ b/src/main/java/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java
@@ -429,15 +429,14 @@
if (objectIdInfo == null) {
// no ObjectId override, but maybe ObjectIdRef?
if (oiw != null) {
- objectIdInfo = intr.findObjectReferenceInfo(accessor,
- new ObjectIdInfo(NAME_FOR_OBJECT_REF, null, null, null));
- oiw = _objectIdWriter.withAlwaysAsId(objectIdInfo.getAlwaysAsId());
+ objectIdInfo = intr.findObjectReferenceInfo(accessor, null);
+ if (objectIdInfo != null) {
+ oiw = _objectIdWriter.withAlwaysAsId(objectIdInfo.getAlwaysAsId());
+ }
}
} else {
- /* Ugh: mostly copied from BeanSerializerBase: but can't easily
- * change it to be able to move to SerializerProvider (where it
- * really belongs)
- */
+ // Ugh: mostly copied from BeanDeserializerBase: but can't easily change it
+ // to be able to move to SerializerProvider (where it really belongs)
// 2.1: allow modifications by "id ref" annotations as well:
objectIdInfo = intr.findObjectReferenceInfo(accessor, objectIdInfo);
diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/AlwaysAsReferenceFirstTest.java b/src/test/java/com/fasterxml/jackson/databind/objectid/AlwaysAsReferenceFirstTest.java
index 9749c0c..f55376a 100644
--- a/src/test/java/com/fasterxml/jackson/databind/objectid/AlwaysAsReferenceFirstTest.java
+++ b/src/test/java/com/fasterxml/jackson/databind/objectid/AlwaysAsReferenceFirstTest.java
@@ -5,6 +5,7 @@
public class AlwaysAsReferenceFirstTest extends BaseMapTest
{
+ // [databind#1255]
@JsonPropertyOrder({ "bar1", "bar2" })
static class Foo {
@@ -20,16 +21,64 @@
public int value = 3;
}
+ // [databind#1607]
+
+ @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="id")
+ static class Value1607
+ {
+ public int value;
+
+ public Value1607() { this(0); }
+ public Value1607(int v) {
+ value = v;
+ }
+}
+ @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="id")
+ @JsonIdentityReference(alwaysAsId=true)
+ static class Value1607ViaClass
+ {
+ public int value;
+
+ public Value1607ViaClass() { this(0); }
+ public Value1607ViaClass(int v) {
+ value = v;
+ }
+ }
+
+ @JsonPropertyOrder(alphabetic=true)
+ static class ReallyAlwaysContainer
+ {
+ public Value1607ViaClass alwaysClass = new Value1607ViaClass(13);
+
+ @JsonIdentityReference(alwaysAsId=true)
+ public Value1607 alwaysProp = new Value1607(13);
+ }
+
+ /*
+ /**********************************************************
+ /* Test methods
+ /**********************************************************
+ */
+
+ private final ObjectMapper MAPPER = new ObjectMapper();
+
+ // [databind#1255]
public void testIssue1255() throws Exception
{
- ObjectMapper mapper = new ObjectMapper();
Foo mo = new Foo();
mo.bar1 = new Bar();
mo.bar2 = mo.bar1;
- String json = mapper.writeValueAsString(mo);
+ String json = MAPPER.writeValueAsString(mo);
- Foo result = mapper.readValue(json, Foo.class);
+ Foo result = MAPPER.readValue(json, Foo.class);
assertNotNull(result);
}
+
+ // [databind#1607]
+ public void testIssue1607() throws Exception
+ {
+ String json = MAPPER.writeValueAsString(new ReallyAlwaysContainer());
+ assertEquals(aposToQuotes("{'alwaysClass':1,'alwaysProp':2}"), json);
+ }
}