MapStruct 1.5.5中@Mapping的qualifiedByName配置失效问题求助
MapStruct集合映射中@Mapping配置被忽略的解决方法
问题现象
使用MapStruct 1.5.5做集合映射时,在集合转换方法上配置的@Mapping(source = "concepts.productId", target = "conceptType", qualifiedByName = "mapConceptType")完全无效,生成的实现类里没有调用mapConceptType的逻辑,断点也进不去。换成expression表达式配置同样不生效。
核心原因
MapStruct处理集合映射的逻辑是:自动遍历集合,调用单个对象的映射方法完成转换。集合方法上的@Mapping注解不会被解析应用到单个对象的映射过程中,所有字段映射规则必须定义在单个对象的映射方法上。
解决方案
步骤1:定义单个对象的映射方法
在Mapper接口中新增单个源Concept到目标Concept的映射方法,将原来集合方法上的所有@Mapping配置移到这个方法上:
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, injectionStrategy = InjectionStrategy.CONSTRUCTOR) public interface ConceptCatalogueToConceptDomain { // 集合方法:仅负责遍历调用单个对象映射,无需配置@Mapping List<Concept> toConceptFromCatalogue(@Context String bankId, List<core.customer.concept.mgmt.config.conceptcatalogue.dto.Concept> concepts); // 单个对象映射:所有字段映射规则都配置在这里 @Mapping(source = "name", target = "name") @Mapping(source = "productId", target = "conceptType", qualifiedByName = "mapConceptType") @Mapping(source = "products.name", target = "products.name") @Mapping(source = "products.productId", target = "products.productId") @Mapping(source = "products.productPartId", target = "products.productPartId") @Mapping(source = "products.status", target = "products.status") @Mapping(source = "products.isMandatory", target = "products.isMandatory") Concept toConcept(@Context String bankId, core.customer.concept.mgmt.config.conceptcatalogue.dto.Concept concept); @Named("mapConceptType") default ConceptType mapConceptType(String productId){ System.out.println("*****************Here: "+productId); return ConceptType.getConceptType(productId); } @AfterMapping default void updateSystemId(@MappingTarget List<Concept> concepts, @Context String bankId) { concepts.forEach(item -> item.setBankId(bankId)); } }
步骤2:简化优化(可选)
因为ConceptType已经提供了静态转换方法getConceptType(String),可以直接让MapStruct自动识别这个类型转换,无需额外定义@Named的default方法:
// 移除@Named的default方法,直接在@Mapping中指定转换逻辑 @Mapping(source = "productId", target = "conceptType") // MapStruct会自动匹配String到ConceptType的转换方法,即枚举的getConceptType静态方法
修正后生成的实现类逻辑
生成的conceptToConcept方法会包含conceptType的转换代码:
protected Concept conceptToConcept(core.customer.concept.mgmt.config.conceptcatalogue.dto.Concept concept, String bankId) { if ( concept == null ) { return null; } Concept concept1 = new Concept(); concept1.setName( concept.getName() ); // 新增的转换逻辑 concept1.setConceptType( mapConceptType( concept.getProductId() ) ); concept1.setProducts( productListToRelatedProductList( concept.getProducts(), bankId ) ); return concept1; }
关键注意点
- 集合映射方法上不要配置
@Mapping,所有字段映射规则必须放在单个对象的映射方法上。 - 如果自定义类型转换方法,确保方法的参数类型和返回类型与源、目标字段类型匹配,且
@Named注解的名称与qualifiedByName一致。 - MapStruct会自动识别符合命名规范的静态转换方法(如
valueOf、getXxx),可以减少自定义代码。
内容的提问来源于stack exchange,提问作者Kaliyug Antagonist
相关产品推荐
相关产品推荐

