Skip to content

Commit 78f609e

Browse files
committed
Fix #2775
1 parent 62329c3 commit 78f609e

File tree

6 files changed

+35
-13
lines changed

6 files changed

+35
-13
lines changed

release-notes/VERSION-2.x

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Project: jackson-databind
77

88
2.12.0-rc2 (not yet released)
99

10+
#2775: Disabling `FAIL_ON_INVALID_SUBTYPE` breaks polymorphic deserialization of Enums
11+
(reported by holgerknoche@github)
1012
#2878: Revert change initially made to fix #2805: change in signature
1113
of `ObjectMapper.treeToValue()` regarding exceptions
1214
#2880: Revert removal of 2.7-deprecated `PropertyNamingStrategy` constants

src/main/java/com/fasterxml/jackson/databind/deser/impl/ExternalTypeHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ public boolean hasTypePropertyName(String n) {
467467
}
468468

469469
public boolean hasDefaultType() {
470-
return _typeDeserializer.getDefaultImpl() != null;
470+
return _typeDeserializer.hasDefaultImpl();
471471
}
472472

473473
/**

src/main/java/com/fasterxml/jackson/databind/jsontype/TypeDeserializer.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ public abstract class TypeDeserializer
7171
*/
7272
public abstract Class<?> getDefaultImpl();
7373

74+
/**
75+
* @since 2.12
76+
*/
77+
public boolean hasDefaultImpl() { return getDefaultImpl() != null; }
78+
7479
/*
7580
/**********************************************************
7681
/* Type deserialization methods

src/main/java/com/fasterxml/jackson/databind/jsontype/impl/AsPropertyTypeDeserializer.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public Object deserializeTypedFromObject(JsonParser p, DeserializationContext ct
7878
return _deserializeWithNativeTypeId(p, ctxt, typeId);
7979
}
8080
}
81-
81+
8282
// but first, sanity check to ensure we have START_OBJECT or FIELD_NAME
8383
JsonToken t = p.currentToken();
8484
if (t == JsonToken.START_OBJECT) {
@@ -115,7 +115,7 @@ public Object deserializeTypedFromObject(JsonParser p, DeserializationContext ct
115115

116116
@SuppressWarnings("resource")
117117
protected Object _deserializeTypedForId(JsonParser p, DeserializationContext ctxt,
118-
TokenBuffer tb, String typeId) throws IOException {
118+
TokenBuffer tb, String typeId) throws IOException {
119119
JsonDeserializer<Object> deser = _findDeserializer(ctxt, typeId);
120120
if (_typeIdVisible) { // need to merge id back in JSON input?
121121
if (tb == null) {
@@ -142,8 +142,9 @@ protected Object _deserializeTypedUsingDefaultImpl(JsonParser p,
142142
DeserializationContext ctxt, TokenBuffer tb) throws IOException
143143
{
144144
// May have default implementation to use
145-
JsonDeserializer<Object> deser = _findDefaultImplDeserializer(ctxt);
146-
if (deser == null) {
145+
// 13-Oct-2020, tatu: As per [databind#2775], need to be careful to
146+
// avoid ending up using "nullifying" deserializer
147+
if (!hasDefaultImpl()) {
147148
// or, perhaps we just bumped into a "natural" value (boolean/int/double/String)?
148149
Object result = TypeDeserializer.deserializeIfNatural(p, ctxt, _baseType);
149150
if (result != null) {
@@ -161,6 +162,11 @@ protected Object _deserializeTypedUsingDefaultImpl(JsonParser p,
161162
}
162163
}
163164
}
165+
}
166+
// ... and here we will check for default implementation handling (either
167+
// genuine, or faked for "dont fail on bad type id")
168+
JsonDeserializer<Object> deser = _findDefaultImplDeserializer(ctxt);
169+
if (deser == null) {
164170
String msg = String.format("missing type id property '%s'",
165171
_typePropertyName);
166172
// even better, may know POJO property polymorphic value would be assigned to
@@ -190,9 +196,8 @@ protected Object _deserializeTypedUsingDefaultImpl(JsonParser p,
190196
*/
191197
@Override
192198
public Object deserializeTypedFromAny(JsonParser p, DeserializationContext ctxt) throws IOException {
193-
/* Sometimes, however, we get an array wrapper; specifically
194-
* when an array or list has been serialized with type information.
195-
*/
199+
// Sometimes, however, we get an array wrapper; specifically
200+
// when an array or list has been serialized with type information.
196201
if (p.hasToken(JsonToken.START_ARRAY)) {
197202
return super.deserializeTypedFromArray(p, ctxt);
198203
}

src/main/java/com/fasterxml/jackson/databind/jsontype/impl/TypeDeserializerBase.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,16 @@ protected TypeDeserializerBase(TypeDeserializerBase src, BeanProperty property)
112112
@Override
113113
public TypeIdResolver getTypeIdResolver() { return _idResolver; }
114114

115-
@Override
115+
@Override
116116
public Class<?> getDefaultImpl() {
117117
return ClassUtil.rawClass(_defaultImpl);
118118
}
119119

120+
@Override
121+
public boolean hasDefaultImpl() {
122+
return (_defaultImpl != null);
123+
}
124+
120125
/**
121126
* @since 2.9
122127
*/

src/test/java/com/fasterxml/jackson/databind/introspect/CustomAnnotationIntrospector1756Test.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.fasterxml.jackson.core.JsonParser;
88
import com.fasterxml.jackson.databind.*;
99
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
10+
import com.fasterxml.jackson.databind.cfg.MapperConfig;
1011
import com.fasterxml.jackson.databind.json.JsonMapper;
1112
import com.fasterxml.jackson.databind.module.SimpleModule;
1213

@@ -89,10 +90,14 @@ public String findImplicitPropertyName(final AnnotatedMember member) {
8990
}
9091

9192
@Override
92-
public boolean hasCreatorAnnotation(Annotated a) {
93-
final AnnotatedConstructor ctor = (AnnotatedConstructor) a;
94-
return (ctor.getParameterCount() > 0)
95-
&& (ctor.getParameter(0).getAnnotation(Field1756.class) != null);
93+
public JsonCreator.Mode findCreatorAnnotation(MapperConfig<?> config, Annotated ann) {
94+
final AnnotatedConstructor ctor = (AnnotatedConstructor) ann;
95+
if (ctor.getParameterCount() > 0) {
96+
if (ctor.getParameter(0).getAnnotation(Field1756.class) != null) {
97+
return JsonCreator.Mode.PROPERTIES;
98+
}
99+
}
100+
return null;
96101
}
97102
}
98103

0 commit comments

Comments
 (0)