Fix #2303
diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x
index d191f27..7af3dee 100644
--- a/release-notes/CREDITS-2.x
+++ b/release-notes/CREDITS-2.x
@@ -837,3 +837,8 @@
Christoph (cfiehe@github.com)
* Contributed #2299: Fix for using jackson-databind in an OSGi environment under Android
(2.9.9)
+
+Cyril Martin (mcoolive@github.com)
+ * Reported #2303: Deserialize null, when java type is "TypeRef of TypeRef of T",
+ does not provide "Type(Type(null))"
+ (2.9.9)
diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x
index 54779ad..720082a 100644
--- a/release-notes/VERSION-2.x
+++ b/release-notes/VERSION-2.x
@@ -16,6 +16,8 @@
(reported by Joffrey B)
#2299: Fix for using jackson-databind in an OSGi environment under Android
(contributed by Christoph F)
+#2303: Deserialize null, when java type is "TypeRef of TypeRef of T", does not provide "Type(Type(null))"
+ (reported by Cyril M)
- Prevent String coercion of `null` in `WritableObjectId` when calling `JsonGenerator.writeObjectId()`,
mostly relevant for formats like YAML that have native Object Ids
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/CreatorProperty.java b/src/main/java/com/fasterxml/jackson/databind/deser/CreatorProperty.java
index 2d42a81..f9badf8 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/CreatorProperty.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/CreatorProperty.java
@@ -131,7 +131,9 @@
if (_valueDeserializer == deser) {
return this;
}
- return new CreatorProperty(this, deser, _nullProvider);
+ // 07-May-2019, tatu: As per [databind#2303], must keep VD/NVP in-sync if they were
+ NullValueProvider nvp = (_valueDeserializer == _nullProvider) ? deser : _nullProvider;
+ return new CreatorProperty(this, deser, nvp);
}
@Override
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/impl/FieldProperty.java b/src/main/java/com/fasterxml/jackson/databind/deser/impl/FieldProperty.java
index d8b38bb..973c85b 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/impl/FieldProperty.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/impl/FieldProperty.java
@@ -89,7 +89,9 @@
if (_valueDeserializer == deser) {
return this;
}
- return new FieldProperty(this, deser, _nullProvider);
+ // 07-May-2019, tatu: As per [databind#2303], must keep VD/NVP in-sync if they were
+ NullValueProvider nvp = (_valueDeserializer == _nullProvider) ? deser : _nullProvider;
+ return new FieldProperty(this, deser, nvp);
}
@Override
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/impl/MethodProperty.java b/src/main/java/com/fasterxml/jackson/databind/deser/impl/MethodProperty.java
index aeeeba6..08111d4 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/impl/MethodProperty.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/impl/MethodProperty.java
@@ -80,7 +80,9 @@
if (_valueDeserializer == deser) {
return this;
}
- return new MethodProperty(this, deser, _nullProvider);
+ // 07-May-2019, tatu: As per [databind#2303], must keep VD/NVP in-sync if they were
+ NullValueProvider nvp = (_valueDeserializer == _nullProvider) ? deser : _nullProvider;
+ return new MethodProperty(this, deser, nvp);
}
@Override
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/impl/ObjectIdReferenceProperty.java b/src/main/java/com/fasterxml/jackson/databind/deser/impl/ObjectIdReferenceProperty.java
index f1b62ab..449cc79 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/impl/ObjectIdReferenceProperty.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/impl/ObjectIdReferenceProperty.java
@@ -50,7 +50,9 @@
if (_valueDeserializer == deser) {
return this;
}
- return new ObjectIdReferenceProperty(this, deser, _nullProvider);
+ // 07-May-2019, tatu: As per [databind#2303], must keep VD/NVP in-sync if they were
+ NullValueProvider nvp = (_valueDeserializer == _nullProvider) ? deser : _nullProvider;
+ return new ObjectIdReferenceProperty(this, deser, nvp);
}
@Override
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/impl/ObjectIdValueProperty.java b/src/main/java/com/fasterxml/jackson/databind/deser/impl/ObjectIdValueProperty.java
index 6316e28..7fe91fc 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/impl/ObjectIdValueProperty.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/impl/ObjectIdValueProperty.java
@@ -51,7 +51,9 @@
if (_valueDeserializer == deser) {
return this;
}
- return new ObjectIdValueProperty(this, deser, _nullProvider);
+ // 07-May-2019, tatu: As per [databind#2303], must keep VD/NVP in-sync if they were
+ NullValueProvider nvp = (_valueDeserializer == _nullProvider) ? deser : _nullProvider;
+ return new ObjectIdValueProperty(this, deser, nvp);
}
@Override
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/impl/SetterlessProperty.java b/src/main/java/com/fasterxml/jackson/databind/deser/impl/SetterlessProperty.java
index 2ce045b..a901f07 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/impl/SetterlessProperty.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/impl/SetterlessProperty.java
@@ -64,7 +64,9 @@
if (_valueDeserializer == deser) {
return this;
}
- return new SetterlessProperty(this, deser, _nullProvider);
+ // 07-May-2019, tatu: As per [databind#2303], must keep VD/NVP in-sync if they were
+ NullValueProvider nvp = (_valueDeserializer == _nullProvider) ? deser : _nullProvider;
+ return new SetterlessProperty(this, deser, nvp);
}
@Override
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/AtomicReferenceDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/AtomicReferenceDeserializer.java
index 916e266..486106c 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/std/AtomicReferenceDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/AtomicReferenceDeserializer.java
@@ -37,9 +37,10 @@
return new AtomicReferenceDeserializer(_fullType, _valueInstantiator,
typeDeser, valueDeser);
}
+
@Override
- public AtomicReference<Object> getNullValue(DeserializationContext ctxt) {
- return new AtomicReference<Object>();
+ public AtomicReference<Object> getNullValue(DeserializationContext ctxt) throws JsonMappingException {
+ return new AtomicReference<Object>(_valueDeserializer.getNullValue(ctxt));
}
@Override
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/ReferenceTypeDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/ReferenceTypeDeserializer.java
index 56bf081..34e502d 100644
--- a/src/main/java/com/fasterxml/jackson/databind/deser/std/ReferenceTypeDeserializer.java
+++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/ReferenceTypeDeserializer.java
@@ -118,10 +118,10 @@
JsonDeserializer<?> valueDeser);
@Override
- public abstract T getNullValue(DeserializationContext ctxt);
+ public abstract T getNullValue(DeserializationContext ctxt) throws JsonMappingException;
@Override
- public Object getEmptyValue(DeserializationContext ctxt) {
+ public Object getEmptyValue(DeserializationContext ctxt) throws JsonMappingException {
return getNullValue(ctxt);
}
diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKAtomicTypesTest.java b/src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKAtomicTypesDeserTest.java
similarity index 91%
rename from src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKAtomicTypesTest.java
rename to src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKAtomicTypesDeserTest.java
index 5721556..40b5a45 100644
--- a/src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKAtomicTypesTest.java
+++ b/src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKAtomicTypesDeserTest.java
@@ -6,10 +6,11 @@
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-public class JDKAtomicTypesTest
+public class JDKAtomicTypesDeserTest
extends com.fasterxml.jackson.databind.BaseMapTest
{
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@@ -93,6 +94,11 @@
public AtomicReference<Object> b = new AtomicReference<Object>();
}
+ // [databind#2303]
+ static class MyBean2303 {
+ public AtomicReference<AtomicReference<Integer>> refRef;
+ }
+
/*
/**********************************************************
/* Test methods
@@ -271,11 +277,25 @@
@SuppressWarnings("unchecked")
public void testNullValueHandling() throws Exception
{
- ObjectMapper mapper = new ObjectMapper();
AtomicReference<Double> inputData = new AtomicReference<Double>();
- String json = mapper.writeValueAsString(inputData);
- AtomicReference<Double> readData = (AtomicReference<Double>) mapper.readValue(json, AtomicReference.class);
+ String json = MAPPER.writeValueAsString(inputData);
+ AtomicReference<Double> readData = (AtomicReference<Double>) MAPPER.readValue(json, AtomicReference.class);
assertNotNull(readData);
assertNull(readData.get());
}
+
+ // [databind#2303]
+ public void testNullWithinNested() throws Exception
+ {
+ final ObjectReader r = MAPPER.readerFor(MyBean2303.class);
+ MyBean2303 intRef = r.readValue(" {\"refRef\": 2 } ");
+ assertNotNull(intRef.refRef);
+ assertNotNull(intRef.refRef.get());
+ assertEquals(intRef.refRef.get().get(), new Integer(2));
+
+ MyBean2303 nullRef = r.readValue(" {\"refRef\": null } ");
+ assertNotNull(nullRef.refRef);
+ assertNotNull(nullRef.refRef.get());
+ assertNull(nullRef.refRef.get().get());
+ }
}