Skip to content

Commit 2c85bd6

Browse files
committed
Fix #3045
1 parent 54160da commit 2c85bd6

3 files changed

Lines changed: 27 additions & 18 deletions

File tree

release-notes/VERSION-2.x

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ Project: jackson-databind
1414
(fix contributed by Migwel@github)
1515
#3038: Two cases of incorrect error reporting about DeserializationFeature
1616
(reported by Jelle V)
17+
#3045: Bug in polymorphic deserialization with `@JsonCreator`, `@JsonAnySetter`,
18+
`JsonTypeInfo.As.EXTERNAL_PROPERTY`
19+
(reported by martineaus83@github)
1720
#3055: Polymorphic subtype deduction ignores `defaultImpl` attribute
1821
(contributed by drekbour@github)
1922
#3056: MismatchedInputException: Cannot deserialize instance of

src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializer.java

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -947,9 +947,15 @@ protected Object deserializeWithExternalTypeId(JsonParser p, DeserializationCont
947947
Object bean)
948948
throws IOException
949949
{
950-
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
951-
final ExternalTypeHandler ext = _externalTypeIdHandler.start();
950+
return _deserializeWithExternalTypeId(p, ctxt, bean,
951+
_externalTypeIdHandler.start());
952+
}
952953

954+
protected Object _deserializeWithExternalTypeId(JsonParser p, DeserializationContext ctxt,
955+
Object bean, ExternalTypeHandler ext)
956+
throws IOException
957+
{
958+
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
953959
for (JsonToken t = p.currentToken(); t == JsonToken.FIELD_NAME; t = p.nextToken()) {
954960
String propName = p.currentName();
955961
t = p.nextToken();
@@ -996,15 +1002,14 @@ protected Object deserializeWithExternalTypeId(JsonParser p, DeserializationCont
9961002
}
9971003

9981004
@SuppressWarnings("resource")
999-
protected Object deserializeUsingPropertyBasedWithExternalTypeId(JsonParser p, DeserializationContext ctxt)
1005+
protected Object deserializeUsingPropertyBasedWithExternalTypeId(JsonParser p,
1006+
DeserializationContext ctxt)
10001007
throws IOException
10011008
{
10021009
final ExternalTypeHandler ext = _externalTypeIdHandler.start();
10031010
final PropertyBasedCreator creator = _propertyBasedCreator;
10041011
PropertyValueBuffer buffer = creator.startBuilding(p, ctxt, _objectIdReader);
1005-
1006-
TokenBuffer tokens = new TokenBuffer(p, ctxt);
1007-
tokens.writeStartObject();
1012+
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
10081013

10091014
JsonToken t = p.currentToken();
10101015
for (; t == JsonToken.FIELD_NAME; t = p.nextToken()) {
@@ -1024,7 +1029,8 @@ protected Object deserializeUsingPropertyBasedWithExternalTypeId(JsonParser p, D
10241029
;
10251030
} else {
10261031
// Last creator property to set?
1027-
if (buffer.assignParameter(creatorProp, _deserializeWithErrorWrapping(p, ctxt, creatorProp))) {
1032+
if (buffer.assignParameter(creatorProp,
1033+
_deserializeWithErrorWrapping(p, ctxt, creatorProp))) {
10281034
t = p.nextToken(); // to move to following FIELD_NAME/END_OBJECT
10291035
Object bean;
10301036
try {
@@ -1033,20 +1039,14 @@ protected Object deserializeUsingPropertyBasedWithExternalTypeId(JsonParser p, D
10331039
wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt);
10341040
continue; // never gets here
10351041
}
1036-
// if so, need to copy all remaining tokens into buffer
1037-
while (t == JsonToken.FIELD_NAME) {
1038-
p.nextToken(); // to skip name
1039-
tokens.copyCurrentStructure(p);
1040-
t = p.nextToken();
1041-
}
10421042
if (bean.getClass() != _beanType.getRawClass()) {
10431043
// !!! 08-Jul-2011, tatu: Could theoretically support; but for now
10441044
// it's too complicated, so bail out
10451045
return ctxt.reportBadDefinition(_beanType, String.format(
10461046
"Cannot create polymorphic instances with external type ids (%s -> %s)",
10471047
_beanType, bean.getClass()));
10481048
}
1049-
return ext.complete(p, ctxt, bean);
1049+
return _deserializeWithExternalTypeId(p, ctxt, bean, ext);
10501050
}
10511051
}
10521052
continue;
@@ -1058,7 +1058,12 @@ protected Object deserializeUsingPropertyBasedWithExternalTypeId(JsonParser p, D
10581058
if (t.isScalarValue()) {
10591059
ext.handleTypePropertyValue(p, ctxt, propName, null);
10601060
}
1061-
buffer.bufferProperty(prop, prop.deserialize(p, ctxt));
1061+
// 19-Feb-2021, tatu: Should probably consider view too?
1062+
if (activeView != null && !prop.visibleInView(activeView)) {
1063+
p.skipChildren();
1064+
} else {
1065+
buffer.bufferProperty(prop, prop.deserialize(p, ctxt));
1066+
}
10621067
continue;
10631068
}
10641069
// external type id (or property that depends on it)?
@@ -1079,7 +1084,6 @@ protected Object deserializeUsingPropertyBasedWithExternalTypeId(JsonParser p, D
10791084
// Unknown: let's call handler method
10801085
handleUnknownProperty(p, ctxt, _valueClass, propName);
10811086
}
1082-
tokens.writeEndObject();
10831087

10841088
// We hit END_OBJECT; resolve the pieces:
10851089
try {

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,17 +95,19 @@ public String toString() {
9595

9696
public void testExternalIdWithAnySetter3045() throws Exception
9797
{
98+
// First cases where the last Creator argument comes last:
9899
_testExternalIdWithAnySetter3045(a2q(
99100
"{'type':'track','data':{'data-internal':'toto'},'time':345}"));
100101
_testExternalIdWithAnySetter3045(a2q(
101102
"{'data':{'data-internal':'toto'},'type':'track', 'time':345}"));
102103

103-
/*
104+
// then a case where it comes in the middle
104105
_testExternalIdWithAnySetter3045(a2q(
105106
"{'data':{'data-internal':'toto'},'time':345, 'type':'track'}"));
107+
108+
// and finally one where we'll start with it
106109
_testExternalIdWithAnySetter3045(a2q(
107110
"{'time':345, 'type':'track', 'data':{'data-internal':'toto'}}"));
108-
*/
109111
}
110112

111113
private void _testExternalIdWithAnySetter3045(String input) throws Exception

0 commit comments

Comments
 (0)