【问题标题】:How to specify select among ambiguous mapping methods in nested Mapstruct mappers?如何在嵌套的 Mapstruct 映射器中指定不明确的映射方法中的选择?
【发布时间】:2020-07-14 20:35:46
【问题描述】:

我们有一个特殊情况,其中 Mapstruct 映射器可以从其依赖项(即 ProductionPlanDetailAutoMapper)中选择 2 种不同的替代方法,但无法这样做,会返回编译错误 SupplyPlanProjectionAutoMapper.java Can't map map value "java.util.List<ProductionPlanDetail>" to "java.util.List<ProductionPlanDetailDTO> ". Consider to declare/implement a mapping method: "java.util.List<ProductionPlanDetailDTO> map(java.util.List<ProductionPlanDetail> value)".

源代码由 2 个映射器组成:概述以及它们各自的代码:

映射器 1:

@Mapper(componentModel = "spring", uses={ProductionPlanDetailAutoMapper.class}) 
public interface SupplyPlanProjectionAutoMapper {

    @Mapping(source = "material.id", target = "materialId")
    public PlanningProjectionDTO convert(PlanningProjection);
    
    public Map<PlanningProjectionDTO, List<ProductionPlanDetailDTO>> convertMapProductionPlanDetail (Map<PlanningProjection, List<ProductionPlanDetail>> map);
}

映射器 2:

@Mapper(componentModel = "spring", uses={RecipeAutoMapper.class})
public interface ProductionPlanDetailAutoMapper {
    
    @Mapping(source = "location.id", target = "locationId")
    @Mapping(source = "receitaProducaoOperacao", target = "productionRecipeOperation")
    @Mapping(source = "dataReferencia", target = "referenceDate")
    @Named(value = "convertWithRecipeDetail")
    public ProductionPlanDetailDTO convertWithRecipeDetail(ProductionPlanDetail);
                
    @Mapping(source = "receitaProducaoOperacao.listaTecnica.materialOutput.id", target = "outputMaterialId")
    @Mapping(source = "receitaProducaoOperacao.listaTecnica.id", target = "billOfMaterialsId")
    @Mapping(source = "receitaProducaoOperacao.receitaProducaoOperacaoCompositeKey.receitaProducao.id", target = "productionRecipeId")
    @Mapping(source = "receitaProducaoOperacao.recursoProdutivo.id", target = "productionResourceId")
    @Mapping(source = "receitaProducaoOperacao.receitaProducaoOperacaoCompositeKey.posicaoOperacao", target = "productionRecipeOperationSequence")
    @Mapping(source = "location.id", target = "locationId")
    @Mapping(source = "dataReferencia", target = "referenceDate")
    @Named(value = "convertWithoutRecipeDetail") 
    public ProductionPlanDetailDTO convertWithoutRecipeDetail(ProductionPlanDetail productionPlanDetail);

    @Named(value = "convertToListWithRecipeDetail") 
    @IterableMapping(qualifiedByName = "convertWithRecipeDetail") 
    public List<ProductionPlanDetailDTO> convertToDTOListWithRecipeDetail (List<ProductionPlanDetail> productionPlanDetailList);
    
    @Named(value = "convertToListWithoutRecipeDetail") 
    @IterableMapping(qualifiedByName = "convertWithoutRecipeDetail") 
    public List<ProductionPlanDetailDTO> convertToDTOListWithoutRecipeDetail (List<ProductionPlanDetail> productionPlanDetailList);
}

第二个映射器中方法之间的歧义通过@Name 和@IterableMapping#QualifiedByName 的结合来解决

我们尝试了相同的方法,将以下注释附加到 convertMapProductionPlanDetail 方法,但无济于事:

@IterableMapping(qualifiedByName = "convertToListWithRecipeDetail")

【问题讨论】:

    标签: java mapstruct


    【解决方案1】:

    尽管 Mapstruct 开发人员已经在文档中没有考虑过这一点。在梳理文档时我发现了这个:valueQualifiedByName

    解决方案是使用 MapMapping 并指定应该使用 2 个 @Name 方法中的哪一个来填充地图的 Values 部分(List(ProductionPlanDetail) 所在的位置):

    @MapMapping(valueQualifiedByName = "convertToDTOListWithRecipeDetail")
    public Map<PlanningProjectionDTO, List<ProductionPlanDetailDTO>> convertMapProductionPlanDetail (Map<PlanningProjection, List<ProductionPlanDetail>> map);
    

    这非常优雅地解决了问题。另一方面,如果转换问题存在于映射键中,则应使用 @MapMapping#keyQualifiedByName 代替。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-04
      • 2023-03-29
      • 2019-07-13
      • 2018-08-24
      • 2018-09-15
      • 2020-08-02
      • 2018-07-09
      • 1970-01-01
      相关资源
      最近更新 更多