diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java index 4886e475e..059a1c7ba 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java @@ -115,8 +115,12 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { this.method = sourceMethod; this.methodMappings = sourceMethod.getMappingOptions().getMappings(); CollectionMappingStrategyPrism cms = sourceMethod.getMapperConfiguration().getCollectionMappingStrategy(); - Map accessors = method.getResultType() - .getEffectiveType() + Type mappingType = method.getResultType(); + if ( !method.isUpdateMethod() ) { + mappingType = mappingType.getEffectiveType(); + } + + Map accessors = mappingType .getPropertyWriteAccessors( cms ); this.targetProperties = accessors.keySet(); @@ -885,7 +889,10 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { types.addAll( propertyMapping.getImportTypes() ); } - types.add( getResultType().getEffectiveType() ); + if ( !isExistingInstanceMapping() ) { + types.addAll( getResultType().getEffectiveType().getImportTypes() ); + } + return types; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java index 3ed0abaf6..cb48c23d5 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java @@ -155,7 +155,11 @@ public class PropertyMapping extends ModelElement { private Type determineTargetType() { // This is a bean mapping method, so we know the result is a declared type - DeclaredType resultType = (DeclaredType) method.getResultType().getEffectiveType().getTypeMirror(); + Type mappingType = method.getResultType(); + if ( !method.isUpdateMethod() ) { + mappingType = mappingType.getEffectiveType(); + } + DeclaredType resultType = (DeclaredType) mappingType.getTypeMirror(); switch ( targetWriteAccessorType ) { case ADDER: diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/TargetReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/TargetReference.java index fc9da4869..5b48d54cc 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/TargetReference.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/TargetReference.java @@ -153,7 +153,7 @@ public class TargetReference { boolean foundEntryMatch; Type resultType = method.getResultType(); - resultType = resultType.getEffectiveType(); + resultType = typeBasedOnMethod( resultType ); // there can be 4 situations // 1. Return type @@ -191,7 +191,7 @@ public class TargetReference { // last entry for ( int i = 0; i < entryNames.length; i++ ) { - Type mappingType = nextType.getEffectiveType(); + Type mappingType = typeBasedOnMethod( nextType ); Accessor targetReadAccessor = mappingType.getPropertyReadAccessors().get( entryNames[i] ); Accessor targetWriteAccessor = mappingType.getPropertyWriteAccessors( cms ).get( entryNames[i] ); boolean isLast = i == entryNames.length - 1; @@ -237,13 +237,13 @@ public class TargetReference { if ( Executables.isGetterMethod( toUse ) || Executables.isFieldAccessor( toUse ) ) { nextType = typeFactory.getReturnType( - (DeclaredType) initial.getEffectiveType().getTypeMirror(), + (DeclaredType) typeBasedOnMethod( initial ).getTypeMirror(), toUse ); } else { nextType = typeFactory.getSingleParameter( - (DeclaredType) initial.getEffectiveType().getTypeMirror(), + (DeclaredType) typeBasedOnMethod( initial ).getTypeMirror(), toUse ).getType(); } @@ -264,6 +264,20 @@ public class TargetReference { } } + /** + * When we are in an update method, i.e. source parameter with {@code @MappingTarget} then the type should + * be itself, otherwise, we always get the effective type. The reason is that when doing updates we always + * search for setters and getters within the updating type. + */ + private Type typeBasedOnMethod(Type type) { + if ( method.isUpdateMethod() ) { + return type; + } + else { + return type.getEffectiveType(); + } + } + /** * A write accessor is not valid if it is {@code null} and it is not last. i.e. for nested target mappings * there must be a write accessor for all entries except the last one. diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/MethodRetrievalProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/MethodRetrievalProcessor.java index 6dfed43c5..19e3d538f 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/MethodRetrievalProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/MethodRetrievalProcessor.java @@ -403,11 +403,6 @@ public class MethodRetrievalProcessor implements ModelElementProcessor