簡體   English   中英

使用新的@SubclassMapping 注解時如何忽略 MapStruct 中的某些字段?

[英]How to ignore some fields in MapStruct when using the new @SubclassMapping annotation?

初始情況

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

域 Model

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

class Apple extends Fruit {
    /* ... */
}

class Banana extends Fruit {
    /* ... */
}

(相應的 1:1 DTO 省略)

映射器

包裝器 class 的映射器

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

水果類的映射器

帶有方法簽名和注釋的抽象Fruit class 的 MapStruct Mapper

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

問題

以上工作正常,直到需要在引用的抽象 class 上忽略字段(例如Fruitweight )。 將此注釋WrapperMapper map方法...

@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. 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 實現將獲得一個新的映射方法,生成到 map 水果。 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)
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM