Using current 1.5.0.Beta2 MapStruct release with JDK 13.
class Wrapper {
private Fruit fruit;
}
abstract class Fruit {
private int weight;
/* ... */
}
class Apple extends Fruit {
/* ... */
}
class Banana extends Fruit {
/* ... */
}
(Corresponding 1:1 DTOs omitted)
@Mapper(uses = {FruitMapper.class})
public interface WrapperMapper {
WrapperDto map(Wrapper wrapper)
}
MapStruct Mapper
for abstract Fruit
class with method signature and annotations:
@Mapper(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION /*...*/)
public interface FruitMapper {
@SubclassMapping(source = Apple.class, target = AppleDto.class)
@SubclassMapping(source = Banana.class, target = BananaDto.class)
FruitDto map(Fruit fruit);
}
The above works fine until a field needs to be ignored on the referenced abstract class (eg the weight
of a Fruit
). Putting this annotation to the WrapperMapper
map
method...
@Mapping(target = "fruit.weight", ignore = true)
WrapperDto map(Wrapper wrapper)
...leads to The return type FruitDto is an abstract class or interface. Provide a non abstract / non interface result type or a factory method.
The return type FruitDto is an abstract class or interface. Provide a non abstract / non interface result type or a factory method.
compile error.
Is there a way to skip fields in MapStruct mapping as outlined without getting this compile error?
What happens is that because you designate it on the WrapperMapper it will not directly use the FruitMapper. Instead the WrapperMapper implementation will get a new mapping method generated to map fruits. MapStruct fails at this attempt and gives you that compile error.
If you add that ignore to the FruitMapper it would inherit it to both subclassmappings:
@SubclassMapping( source = Apple.class, target = AppleDto.class )
@SubclassMapping( source = Banana.class, target = BananaDto.class )
@Mapping( target = "weight", ignore = true )
FruitDto map( Fruit fruit );
In case you want to have a mapping with weights and one without weights you could add the @org.mapstruct.Named
annotation to the one without weights and then use this at the WrappedMapper.
like this:
@Mapper(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION /*...*/)
public interface FruitMapper {
@SubclassMapping( source = Apple.class, target = AppleDto.class )
@SubclassMapping( source = Banana.class, target = BananaDto.class )
FruitDto map( Fruit fruit );
@SubclassMapping( source = Apple.class, target = AppleDto.class )
@SubclassMapping( source = Banana.class, target = BananaDto.class )
@Mapping( target = "weight", ignore = true )
@Named( "NoWeights" )
FruitDto map( Fruit fruit );
}
@Mapper(uses = {FruitMapper.class})
public interface WrapperMapper {
@Mapping( target = "fruit", qualifiedByName = "NoWeights" )
WrapperDto map(Wrapper wrapper)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.