Skip to content

Commit f7e476e

Browse files
committed
Fix #1256
1 parent 9c2e89b commit f7e476e

File tree

6 files changed

+38
-15
lines changed

6 files changed

+38
-15
lines changed

release-notes/VERSION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Project: jackson-databind
66

77
2.8.1 (not yet released)
88

9+
#1256: `Optional.empty()` not excluded if property declared with type `Object`
910
#1288: Type id not exposed for `JsonTypeInfo.As.EXTERNAL_PROPERTY` even when `visible` set to `true`
1011
(reported by libetl@github)
1112
#1289: Optimize construction of `ArrayList`, `LinkedHashMap` instances

src/main/java/com/fasterxml/jackson/databind/ser/PropertyBuilder.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,20 @@ protected BeanPropertyWriter buildWriter(SerializerProvider prov,
103103
inclusion = JsonInclude.Include.ALWAYS;
104104
}
105105

106+
// 12-Jul-2016, tatu: [databind#1256] Need to make sure we consider type refinement
107+
JavaType actualType = (serializationType == null) ? declaredType : serializationType;
108+
106109
switch (inclusion) {
107110
case NON_DEFAULT:
108111
// 11-Nov-2015, tatu: This is tricky because semantics differ between cases,
109112
// so that if enclosing class has this, we may need to values of property,
110113
// whereas for global defaults OR per-property overrides, we have more
111114
// static definition. Sigh.
112115
// First: case of class specifying it; try to find POJO property defaults
113-
JavaType t = (serializationType == null) ? declaredType : serializationType;
114116
if (_defaultInclusion.getValueInclusion() == JsonInclude.Include.NON_DEFAULT) {
115-
valueToSuppress = getPropertyDefaultValue(propDef.getName(), am, t);
117+
valueToSuppress = getPropertyDefaultValue(propDef.getName(), am, actualType);
116118
} else {
117-
valueToSuppress = getDefaultValue(t);
119+
valueToSuppress = getDefaultValue(actualType);
118120
}
119121
if (valueToSuppress == null) {
120122
suppressNulls = true;
@@ -129,7 +131,7 @@ protected BeanPropertyWriter buildWriter(SerializerProvider prov,
129131
// always suppress nulls
130132
suppressNulls = true;
131133
// and for referential types, also "empty", which in their case means "absent"
132-
if (declaredType.isReferenceType()) {
134+
if (actualType.isReferenceType()) {
133135
valueToSuppress = BeanPropertyWriter.MARKER_FOR_EMPTY;
134136
}
135137
break;
@@ -145,7 +147,7 @@ protected BeanPropertyWriter buildWriter(SerializerProvider prov,
145147
case ALWAYS: // default
146148
default:
147149
// we may still want to suppress empty collections, as per [JACKSON-254]:
148-
if (declaredType.isContainerType()
150+
if (actualType.isContainerType()
149151
&& !_config.isEnabled(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS)) {
150152
valueToSuppress = BeanPropertyWriter.MARKER_FOR_EMPTY;
151153
}

src/main/java/com/fasterxml/jackson/databind/type/TypeFactory.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,7 @@ public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass)
401401
}
402402

403403
// If not, we'll need to do more thorough forward+backwards resolution. Sigh.
404-
// !!! TODO (as of 28-Jan-2016, at least)
405-
404+
406405
// 20-Oct-2015, tatu: Container, Map-types somewhat special. There is
407406
// a way to fully resolve and merge hierarchies; but that gets expensive
408407
// so let's, for now, try to create close-enough approximation that

src/test/java/com/fasterxml/jackson/databind/deser/TestJDKAtomicTypes.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.fasterxml.jackson.annotation.*;
88
import com.fasterxml.jackson.databind.ObjectMapper;
99
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
10+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
1011

1112
public class TestJDKAtomicTypes
1213
extends com.fasterxml.jackson.databind.BaseMapTest
@@ -86,6 +87,13 @@ static class LCStringWrapper {
8687
public LCStringWrapper() { }
8788
}
8889

90+
@JsonPropertyOrder({ "a", "b" })
91+
static class Issue1256Bean {
92+
@JsonSerialize(as=AtomicReference.class)
93+
public Object a = new AtomicReference<Object>();
94+
public AtomicReference<Object> b = new AtomicReference<Object>();
95+
}
96+
8997
/*
9098
/**********************************************************
9199
/* Test methods
@@ -250,4 +258,13 @@ public void testWithCustomDeserializer() throws Exception
250258
LCStringWrapper.class);
251259
assertEquals("foobar", w.value.get());
252260
}
261+
262+
public void testEmpty1256() throws Exception
263+
{
264+
ObjectMapper mapper = new ObjectMapper();
265+
mapper.setSerializationInclusion(JsonInclude.Include.NON_ABSENT);
266+
267+
String json = mapper.writeValueAsString(new Issue1256Bean());
268+
assertEquals("{}", json);
269+
}
253270
}

src/test/java/com/fasterxml/jackson/databind/jsontype/ext/ExternalTypeIdTest1288.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,15 @@
11
package com.fasterxml.jackson.databind.jsontype.ext;
22

3-
import java.io.IOException;
43
import java.util.UUID;
54

6-
import org.junit.Test;
7-
85
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
96
import com.fasterxml.jackson.annotation.JsonTypeInfo;
107
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
118

12-
import com.fasterxml.jackson.core.JsonParseException;
13-
149
import com.fasterxml.jackson.databind.*;
1510
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
1611
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
1712
import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver;
18-
import com.fasterxml.jackson.databind.jsontype.ext.ExternalTypeIdTest1288.ClassesWithBuilder.PaymentMean;
1913
import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase;
2014

2115
@SuppressWarnings("hiding")
@@ -510,12 +504,10 @@ public void testVisibleExternalTypeId1288() throws Exception
510504
+ "\"csc\":666,\"address\":\"10 boulevard de Sebastopol\",\"zip_code\":\"75001\",\"city\":\"Paris\",\"province\":\"Ile-de-France\",\"country_code\":\"FR\",\"description\":\"John Doe personal credit card\"}}";
511505
final String asJson2 = "{\"form_of_payment\":\"INSTRUMENTED_CREDIT_CARD\",\"payment_details\":{\"payment_instrument_id\":\"00000000-0000-0000-0000-000000000000\", \"name\":\"Mr John Doe encrypted credit card\"}}";
512506
final ObjectMapper objectMapper = new ObjectMapper ().setPropertyNamingStrategy (PropertyNamingStrategy.SNAKE_CASE);
513-
// .disable (DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
514507

515508
ClassesWithoutBuilder.PaymentMean ob1 = objectMapper.readValue (asJson1, ClassesWithoutBuilder.PaymentMean.class);
516509
assertNotNull(ob1);
517510
ClassesWithBuilder.PaymentMean ob2 = objectMapper.readValue (asJson2, ClassesWithBuilder.PaymentMean.class);
518511
assertNotNull(ob2);
519-
520512
}
521513
}

src/test/java/com/fasterxml/jackson/databind/type/TestJavaType.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,4 +185,16 @@ public void testAnchorTypeForRefTypes() throws Exception
185185
assertFalse(rt.isAnchorType());
186186
assertEquals(AtomicReference.class, rt.getAnchorType().getRawClass());
187187
}
188+
189+
// for [databind#1290]
190+
public void testObjectToReferenceSpecialization() throws Exception
191+
{
192+
TypeFactory tf = TypeFactory.defaultInstance();
193+
JavaType base = tf.constructType(Object.class);
194+
assertTrue(base.isJavaLangObject());
195+
196+
JavaType sub = tf.constructSpecializedType(base, AtomicReference.class);
197+
assertEquals(AtomicReference.class, sub.getRawClass());
198+
assertTrue(sub.isReferenceType());
199+
}
188200
}

0 commit comments

Comments
 (0)