【问题标题】:Mapstruct extending multiple interfaces containing method with the same signatureMapstruct 扩展包含具有相同签名的方法的多个接口
【发布时间】:2020-02-05 10:14:43
【问题描述】:

我在我的项目中使用了 2 个库,它们需要具有不同接口的映射器:

public interface FirstLibraryMapper<T, M> {

    M mapToDto(T domain);

    List<M> mapToDto(List<T> domains);

}

public interface SecondLibraryMapper<T, M> {

    M mapToDto(T domain);

}

我想使用 mapstruct 创建一个映射器 bean,该映射器 bean 将通过接口注入库组件中,因为两个接口都有一个具有精确签名的方法:

@Mapper
public interface MyMapper extends FirstLibraryMapper<MyDomain, MyDto>, SecondLibraryMapper<MyDomain, MyDto> {

}

当我尝试编译时,我得到了这个错误:

Ambiguous mapping methods found for mapping collection element to MyDto: MyDto mapToDto(MyDomain arg0), MyDto mapToDto(MyDomain arg0).

我可以通过使用@Named 和@IterableMapping 绕过这个问题,但感觉错误且笨拙。如果 mapstruct 处理器具有与第一个方法完全相同的签名,为什么它不能忽略第二种方法?我应该在他们的 github 页面上提出问题吗?还是在这种情况下我错了?

【问题讨论】:

  • 您的 Mapper 正在映射具有相同签名的相同对象? java怎么知道区分它们?
  • Why can't mapstruct processor ignore。但为什么它应该忽略呢?尽管签名相同,但两种方法的行为可能不同。 MapStruct 会如何选择你到底想要什么?
  • @NikolaiShevchenko 如果我错了,请纠正我,但是如果在 impl 类中只有一个方法可以从两个接口访问,那么方法行为有何不同?

标签: java spring mapstruct


【解决方案1】:

您是否考虑过在某种外观模式下组合这两个映射器?

@Mapper
public interface MyFirstMapper extends FirstLibraryMapper<MyDomain, MyDto> {
}

@Mapper
public interface MySecondMapper extends SecondLibraryMapper<MyDomain, MyDto> {
}

@Service
public class MyMapperFacade extends FirstLibraryMapper<MyDomain, MyDto>, SecondLibraryMapper<MyDomain, MyDto> {

    @Autowired
    private MyFirstMapper firstMapper;

    @Autowired
    private MySecondMapper secondMapper;

    @Override
    public MyDto mapToDto(MyDomain domain) {
        return firstMapper.mapToDto(domain); // always delegate to FirstLibraryMapper
    }
}

【讨论】:

  • 是的,我做到了,但这需要复制映射,我想避免它
【解决方案2】:

通过覆盖结果映射器中的方法解决了问题,这仍然有点笨拙,但似乎可以解决问题。

@Mapper
public interface MyMapper extends FirstLibraryMapper<MyDomain, MyDto>, SecondLibraryMapper<MyDomain, MyDto> {

    @Override
    MyDto mapToDto(MyDomain domain);

}

【讨论】:

    【解决方案3】:

    你可以有一个映射器。您不应指定映射类型:

    @Mapper
    public interface Mapper {
    
        Dto1 mapToDto1(Domain1 domain1);
    
        List<Dto1> mapToDto1(List<Domain1> domains1);
    
        Dto2 mapToDto2(Domain2 domain2);
    
    }
    

    【讨论】:

    • 问题是 - FirstLibraryMapper 和 SecondLibraryMapper 是两个不同库的接口,不应相互耦合。碰巧我在同一个组件中使用它们。
    • @PashchenkoDenis 我认为 MapStruct 没有这个功能。你应该向他们提出一张票
    猜你喜欢
    • 2011-02-19
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 2018-11-04
    • 1970-01-01
    • 2019-08-22
    • 2011-01-23
    相关资源
    最近更新 更多