如何在嵌套Mapstruct映射器中的模糊映射方法中指定选择?

时间:2020-07-14 20:35:46

标签: java mapstruct

在特殊情况下,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个映射器组成:概述及其各自的代码:

Mapstruct Diagram

地图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")

1 个答案:

答案 0 :(得分:1)

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

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

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

可以很优雅地解决问题。另一方面,如果转换问题存在于地图密钥中,则应改用@ MapMapping#keyQualifiedByName。