diff --git a/NEXT_RELEASE_CHANGELOG.md b/NEXT_RELEASE_CHANGELOG.md index a3ea4e502..438f4e3a6 100644 --- a/NEXT_RELEASE_CHANGELOG.md +++ b/NEXT_RELEASE_CHANGELOG.md @@ -5,6 +5,7 @@ ### Bugs * Inverse Inheritance Strategy not working for ignored mappings only with target (#3652) +* Inconsistent ambiguous mapping method error when using `SubclassMapping`: generic vs raw types (#3668) * Fix regression when using `InheritInverseConfiguration` with nested target properties and reversing `target = "."` (#3670) ### Documentation 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 6535b0701..1bec5038c 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 @@ -295,7 +295,9 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { } } - boolean applyImplicitMappings = !mappingReferences.isRestrictToDefinedMappings(); + // If defined mappings should not be handled then we should not apply implicit mappings + boolean applyImplicitMappings = + shouldHandledDefinedMappings && !mappingReferences.isRestrictToDefinedMappings(); if ( applyImplicitMappings ) { applyImplicitMappings = beanMapping == null || !beanMapping.isignoreByDefault(); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Child.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Child.java new file mode 100644 index 000000000..3c10c4d47 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Child.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3668; + +public abstract class Child { + + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public static class ChildA extends Child { } + + public static class ChildB extends Child { } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ChildDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ChildDto.java new file mode 100644 index 000000000..458cc57a9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ChildDto.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3668; + +public abstract class ChildDto { + + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public static class ChildDtoA extends ChildDto { } + + public static class ChildDtoB extends ChildDto { } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ChildMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ChildMapper.java new file mode 100644 index 000000000..c381a99fc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ChildMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3668; + +import org.mapstruct.Mapper; +import org.mapstruct.SubclassExhaustiveStrategy; +import org.mapstruct.SubclassMapping; + +@Mapper(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION) +public interface ChildMapper { + + @SubclassMapping(target = Child.ChildA.class, source = ChildDto.ChildDtoA.class) + @SubclassMapping(target = Child.ChildB.class, source = ChildDto.ChildDtoB.class) + Child toEntity(ChildDto childDto); + + @SubclassMapping(target = ChildDto.ChildDtoA.class, source = Child.ChildA.class) + @SubclassMapping(target = ChildDto.ChildDtoB.class, source = Child.ChildB.class) + ChildDto toDto(Child child); + + Child.ChildA toEntity(ChildDto.ChildDtoA childDto); + + ChildDto.ChildDtoA toDto(Child.ChildA child); + + Child.ChildB toEntity(ChildDto.ChildDtoB childDto); + + ChildDto.ChildDtoB toDto(Child.ChildB child); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Issue3668Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Issue3668Test.java new file mode 100644 index 000000000..a35ac70dc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Issue3668Test.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3668; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3668") +@WithClasses({ + Child.class, + ChildDto.class, + ChildMapper.class, + Parent.class, + ParentDto.class, + ParentMapper.class, +}) +class Issue3668Test { + + @ProcessorTest + void shouldCompile() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Parent.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Parent.java new file mode 100644 index 000000000..900a7fa68 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Parent.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3668; + +public abstract class Parent { + + private Long id; + + private T child; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public T getChild() { + return child; + } + + public void setChild(T child) { + this.child = child; + } + + public static class ParentA extends Parent { } + + public static class ParentB extends Parent { } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ParentDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ParentDto.java new file mode 100644 index 000000000..f4736ceef --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ParentDto.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3668; + +public abstract class ParentDto { + + private Long id; + + private T child; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public T getChild() { + return child; + } + + public void setChild(T child) { + this.child = child; + } + + public static class ParentDtoA extends ParentDto { } + + public static class ParentDtoB extends ParentDto { } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ParentMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ParentMapper.java new file mode 100644 index 000000000..484ddbc93 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ParentMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3668; + +import org.mapstruct.Mapper; +import org.mapstruct.SubclassExhaustiveStrategy; +import org.mapstruct.SubclassMapping; + +@Mapper(uses = { ChildMapper.class }, subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION) +public interface ParentMapper { + + @SubclassMapping(target = Parent.ParentA.class, source = ParentDto.ParentDtoA.class) + @SubclassMapping(target = Parent.ParentB.class, source = ParentDto.ParentDtoB.class) + Parent toEntity(ParentDto parentDto); + + @SubclassMapping(target = ParentDto.ParentDtoA.class, source = Parent.ParentA.class) + @SubclassMapping(target = ParentDto.ParentDtoB.class, source = Parent.ParentB.class) + ParentDto toDto(Parent parent); + + Parent.ParentA toEntity(ParentDto.ParentDtoA parentDto); + + ParentDto.ParentDtoA toDto(Parent.ParentA parent); + + Parent.ParentB toEntity(ParentDto.ParentDtoB parentDto); + + ParentDto.ParentDtoB toDto(Parent.ParentB parent); + +}