diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index b1ed415a51..f51d991205 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -1081,26 +1081,26 @@ Robert Diebels (RobertDiebels@github) Joseph Koshakow (jkosh44@github) * Contributed fix for #2515: `ObjectMapper.registerSubtypes(NamedType...)` doesn't allow registering the same POJO for two different type ids - (2.11.0) + (2.11.0) Haowei Wen (yushijinhun@github) * Reported #2565: Java 8 `Optional` not working with `@JsonUnwrapped` on unwrappable type - (2.11.0) + (2.11.0) Bartosz Baranowski (baranowb@github) * Reported #2589: `DOMDeserializer`: setExpandEntityReferences(false) may not prevent external entity expansion in all cases - (2.11.0) + (2.11.0) Oleksii Khomchenko (gagoman@github) * Reported, contributed fix for #2592: `ObjectMapper.setSerializationInclusion()` is ignored for `JsonAnyGetter` - (2.11.0) + (2.11.0) Oleksandr Poslavskyi (alevskyi@github) * Contributed fix for #1983: Polymorphic deserialization should handle case-insensitive Type Id property name if `MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES` is enabled - (2.11.0) + (2.11.0) Simone D'Avico (simonedavico@github) * Reported #2632: Failure to resolve generic type parameters on serialization @@ -1125,3 +1125,7 @@ Johannes Kuhn (DasBrain@github) deserializer properties (2.11.1) +Frank Schmager (fschmager@github) + * Reported #2757: "Conflicting setter definitions for property" exception for `Map` + subtype during deserialization + (2.11.1) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index d9e94a5b0e..62b1378080 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -14,6 +14,9 @@ Project: jackson-databind #2755: `StdSubtypeResolver` is not thread safe (possibly due to copy not being made with `ObjectMapper.copy()`) (reported by tjwilson90@github) +#2757: "Conflicting setter definitions for property" exception for `Map` + subtype during deserialization + (reported by Frank S) #2759: Rearranging of props when property-based generator is in use leads to incorrect output (reported by Oleg C) diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/BeanPropertyDefinition.java b/src/main/java/com/fasterxml/jackson/databind/introspect/BeanPropertyDefinition.java index caa2663c69..075a87dbac 100644 --- a/src/main/java/com/fasterxml/jackson/databind/introspect/BeanPropertyDefinition.java +++ b/src/main/java/com/fasterxml/jackson/databind/introspect/BeanPropertyDefinition.java @@ -224,12 +224,15 @@ public AnnotatedMember getNonConstructorMutator() { * the highest precedence in current context (getter method when serializing, * if available, and so forth), if any. *
+ * Note: may throw {@link IllegalArgumentException} in case problems are found + * trying to getter or setter info. + *
* Note: abstract since 2.5
*
* @since 2.1
*/
public abstract AnnotatedMember getPrimaryMember();
-
+
/*
/**********************************************************
/* More refined access to configuration features
diff --git a/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertyBuilder.java b/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertyBuilder.java
index da593dc64e..a171f157de 100644
--- a/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertyBuilder.java
+++ b/src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertyBuilder.java
@@ -239,16 +239,20 @@ public PropertyMetadata getMetadata() {
* Helper method that contains logic for accessing and merging all setter
* information that we needed, regarding things like possible merging
* of property value, and handling of incoming nulls.
+ * Only called for deserialization purposes.
*/
protected PropertyMetadata _getSetterInfo(PropertyMetadata metadata)
{
boolean needMerge = true;
Nulls valueNulls = null;
Nulls contentNulls = null;
-
+
// Slightly confusing: first, annotations should be accessed via primary member
- // (mutator); but accessor is needed for actual merge operation. So:
- AnnotatedMember prim = getPrimaryMember();
+ // (mutator); but accessor is needed for actual merge operation. So
+
+ // 20-Jun-2020, tatu: Unfortunately strict checks lead to [databind#2757]
+ // so we will need to try to avoid them at this point
+ AnnotatedMember prim = getPrimaryMemberUnchecked();
AnnotatedMember acc = getAccessor();
if (prim != null) {
@@ -272,7 +276,10 @@ protected PropertyMetadata _getSetterInfo(PropertyMetadata metadata)
// If not, config override?
// 25-Oct-2016, tatu: Either this, or type of accessor...
if (needMerge || (valueNulls == null) || (contentNulls == null)) {
- Class> rawType = getRawPrimaryType();
+ // 20-Jun-2020, tatu: Related to [databind#2757], need to find type
+ // but keeping mind that type for setters is trickier; and that
+ // generic typing gets tricky as well.
+ Class> rawType = _rawTypeOf(prim);
ConfigOverride co = _config.getConfigOverride(rawType);
JsonSetter.Value setterInfo = co.getSetterInfo();
if (setterInfo != null) {
@@ -330,7 +337,6 @@ public JavaType getPrimaryType() {
// 09-Feb-2017, tatu: Not sure if this or `null` but...
return TypeFactory.unknownType();
}
- return m.getType();
}
return m.getType();
}
@@ -577,6 +583,45 @@ public AnnotatedMember getPrimaryMember() {
return m;
}
+ // Sometimes we need to actually by-pass failures related to conflicting
+ // getters or setters (see [databind#2757] for specific example); if so,
+ // this method is to be used instead of `getPrimaryMember()`
+ // @since 2.11.1
+ protected AnnotatedMember getPrimaryMemberUnchecked() {
+ if (_forSerialization) { // Inlined `getAccessor()` logic:
+ // Inlined `getGetter()`:
+ if (_getters != null) {
+ return _getters.value;
+ }
+ // Inlined `getField()`:
+ if (_fields != null) {
+ return _fields.value;
+ }
+ return null;
+ }
+
+ // Otherwise, inlined `getMutator()` logic:
+
+ // Inlined `getConstructorParameter()`:
+ if (_ctorParameters != null) {
+ return _ctorParameters.value;
+ }
+ // Inlined `getSetter()`:
+ if (_setters != null) {
+ return _setters.value;
+ }
+ // Inlined `getField()`:
+ if (_fields != null) {
+ return _fields.value;
+ }
+ // but to support setterless-properties, also include part of
+ // `getAccessor()` not yet covered, `getGetter()`:
+ if (_getters != null) {
+ return _getters.value;
+ }
+ return null;
+ }
+
protected int _getterPriority(AnnotatedMethod m)
{
final String name = m.getName();
@@ -1220,6 +1265,26 @@ protected