如何在嵌套的 Mapstruct 映射器中的模糊映射方法中指定 select?
How to specify select among ambiguous mapping methods in nested Mapstruct mappers?
我们有一个特殊情况,其中 Mapstruct 映射器可以从其依赖项(即 ProductionPlanDetailAutoMapper)中选择 2 种不同的替代方法,但是无法这样做,returns 编译错误 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")
虽然文档中没有,但 Mapstruct 开发人员已经考虑过了。在梳理文档时我发现了这个:valueQualifiedByName
解决方案是使用 MapMapping 并指定应使用 2 个 @Name 方法中的哪一个来填充地图的值部分(List(ProductionPlanDetail) 所在的位置):
@MapMapping(valueQualifiedByName = "convertToDTOListWithRecipeDetail")
public Map<PlanningProjectionDTO, List<ProductionPlanDetailDTO>> convertMapProductionPlanDetail (Map<PlanningProjection, List<ProductionPlanDetail>> map);
这很优雅地解决了这个问题。另一方面,如果转换问题出在地图键上,则应改用@MapMapping#keyQualifiedByName。
我们有一个特殊情况,其中 Mapstruct 映射器可以从其依赖项(即 ProductionPlanDetailAutoMapper)中选择 2 种不同的替代方法,但是无法这样做,returns 编译错误 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")
虽然文档中没有,但 Mapstruct 开发人员已经考虑过了。在梳理文档时我发现了这个:valueQualifiedByName
解决方案是使用 MapMapping 并指定应使用 2 个 @Name 方法中的哪一个来填充地图的值部分(List(ProductionPlanDetail) 所在的位置):
@MapMapping(valueQualifiedByName = "convertToDTOListWithRecipeDetail")
public Map<PlanningProjectionDTO, List<ProductionPlanDetailDTO>> convertMapProductionPlanDetail (Map<PlanningProjection, List<ProductionPlanDetail>> map);
这很优雅地解决了这个问题。另一方面,如果转换问题出在地图键上,则应改用@MapMapping#keyQualifiedByName。