初始情况
使用当前的1.5.0Beta 2 MapStruct版本和JDK 13。
领域模型
class Wrapper {
private Fruit fruit;
}
abstract class Fruit {
private int weight;
/* ... */
class Apple extends Fruit {
/* ... */
class Banana extends Fruit {
/* ... */
}
(相应略去1:1 DTO)
地图绘制者
包装类的Mapper
@Mapper(uses = {FruitMapper.class})
public interface WrapperMapper {
WrapperDto map(Wrapper wrapper)
}
水果类地图(Es)
具有方法签名和注释的MapStruct
Mapper
for
抽象
Fruit
类:
@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);
}
问题
上面的内容可以正常工作,直到需要在引用的抽象类上忽略一个字段(例如,
weight
的
Fruit
)。将此注释放入
WrapperMapper
map
方法..。
@Mapping(target = "fruit.weight", ignore = true)
WrapperDto map(Wrapper wrapper)
...leads到
The return type FruitDto is an abstract class or interface. Provide a non abstract / non interface result type or a factory method.
编译错误。
问题
是否有一种方法可以跳过MapStruct映射中的字段而不获取此编译错误?
发布于 2022-01-02 13:45:36
原因
因为您在WrapperMapper上指定了它,所以它不会直接使用FruitMapper。相反,WrapperMapper实现将得到一个新的映射方法来映射结果。MapStruct在此尝试中失败,并给出了编译错误。
解决方案
如果将该忽略添加到FruitMapper中,它将继承到两个子类映射:
@SubclassMapping( source = Apple.class, target = AppleDto.class )
@SubclassMapping( source = Banana.class, target = BananaDto.class )
@Mapping( target = "weight", ignore = true )
FruitDto map( Fruit fruit );
如果您想要有权重的映射和没有权重的映射,您可以将
@org.mapstruct.Named
注释添加到没有权重的映射中,然后在WrappedMapper中使用该注释。
就像这样:
@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 );