如何在使用新的@SubclassMapping注释时忽略MapStruct中的一些字段



初始情况

使用JDK 13的当前1.5.0.Beta2 MapStruct版本。

域模型

class Wrapper {
private Fruit fruit;
}
abstract class Fruit {
private int weight;
/* ... */
}
class Apple extends Fruit {
/* ... */
}
class Banana extends Fruit {
/* ... */
}

(省略了相应的1:1 DTO(

映射器

Wrapper类的映射器

@Mapper(uses = {FruitMapper.class})
public interface WrapperMapper {
WrapperDto map(Wrapper wrapper)
}

水果类映射器

抽象Fruit类的MapStructMapper,带有方法签名和注释:

@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);
}

问题

在引用的抽象类(例如Fruitweight(上的字段需要被忽略之前,上述操作一直很好。将此注释放到WrapperMappermap方法中。。。

@Mapping(target = "fruit.weight", ignore = true)
WrapperDto map(Wrapper wrapper)

导致The return type FruitDto is an abstract class or interface. Provide a non abstract / non interface result type or a factory method.编译错误。

问题

有没有一种方法可以跳过MapStruct映射中的字段,而不会出现编译错误?

原因

结果是,因为您在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 );
}
@Mapper(uses = {FruitMapper.class})
public interface WrapperMapper {
@Mapping( target = "fruit", qualifiedByName = "NoWeights" )
WrapperDto map(Wrapper wrapper)
}

相关内容

  • 没有找到相关文章

最新更新