【问题标题】:Mapstruct 'aftermapping' not called未调用 Mapstruct 'aftermapping'
【发布时间】:2019-05-10 07:23:14
【问题描述】:

问题是,用@AfterMapping 注释的方法根本没有被调用。从testToEntityMapping 转到toEntity 方法,但它不调用任何toEntityAfterMapping() 方法。为什么 ?可能吗 ?如何使用 MapStruct 实现这一点?

(这里我准备了一个没有意义的场景,但它完全抓住了我的问题的本质)
实体:

public class Ford {
    private String color;
    private String market;
    private int totalWidth;

    //getters and setters omitted for brevity
}

Dtos:

public abstract class FordDto {
    public String market;
    public String color;

    //getters and setters omitted for brevity
}

public class EuropeanFordDto extends FordDto{
    private int totalWidth;

    public int getTotalWidth() {
        return totalWidth + 2;//"+2" for EU market
    }
    //setter omitted for brevity
}

public class AmericanFordDto extends FordDto{
    private int totalWidth;

    public int getTotalWidth() {
        return totalWidth + 1;//"+1" for US market
    }

    //setter omitted for brevity
}

映射器:

public abstract class FordMapper<D extends FordDto> {
    public Ford toEntity(D dto) {

        /* fill in fields common to both ford versions */

        final Ford ford = new Ford();

        ford.setColor(dto.getColor());
        ford.setMarket(dto.getMarket());

        return ford;
    }
}
@Mapper(componentModel = "spring")
public abstract class EuropeanFordMapper extends FordMapper<EuropeanFordDto> {

    @AfterMapping
    public void toEntityAfterMapping(final EuropeanFordDto dto, @MappingTarget final Ford entity) {

        /* Fill in fields related to european version of the ford */

        entity.setTotalWidth(dto.getTotalWidth());
    }
}
@Mapper(componentModel = "spring")
public abstract class AmericanFordMapper extends FordMapper<AmericanFordDto> {

    @AfterMapping
    public void toEntityAfterMapping(final AmericanFordDto dto, @MappingTarget final Ford entity) {

        /* Fill in fields related to american version of the ford */

        entity.setTotalWidth(dto.getTotalWidth());
    }
}

服务:

@Service
public class CarService {

    @Autowired
    private AmericanFordMapper americanFordMapper;
    @Autowired
    private EuropeanFordMapper europeanFordMapper;

    public void testToEntityMapping(final FordDto dto) {

        if (dto instanceof AmericanFordDto) {
            americanFordMapper.toEntity((AmericanFordDto) dto);
        } else {
            europeanFordMapper.toEntity((EuropeanFordDto) dto);
        }
    }
}

【问题讨论】:

    标签: mapstruct


    【解决方案1】:

    好的,比我想象的要简单。

    public interface FordMapper<D extends FordDto> {
        
        @Mapping(target = "totalWidth", ignore=true)
        public abstract Ford toEntity(D dto);
    }
    

    你甚至可以窥视toEntity()方法中的实现,有一个对toEntityAfterMapping()的调用,因此一切都是正确的,并且符合我们想要的结果。

    【讨论】:

    • 我完全错过了FordMapper 中您的方法不是抽象的。我会编辑问题并采用第二种方法,即 MapStruct 的做事方式。您甚至可以将 abstract class 设为 interface
    • 我已经编辑了这个问题。希望它就像你希望的那样。干杯。
    【解决方案2】:

    我对同一问题的解决方案是我忘记在我的@AfterMapping 方法中添加“默认”关键字(我使用了接口)。在该方法出现在生成的代码中之后。

    并且不要忘记在进行更改后运行 mvn/gradle clean 并编译。

    【讨论】:

    • 或者'static'如果你使用抽象类
    猜你喜欢
    • 2022-11-19
    • 1970-01-01
    • 2022-12-17
    • 2022-10-15
    • 2021-12-08
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    • 2022-10-16
    相关资源
    最近更新 更多