MapStruct中qualifiedByName与@Named注解不生效问题
解决MapStruct中@Named方法匹配失败的编译异常
问题场景
使用MapStruct 1.5.5.Final + JDK 17开发时,在UndoIssueConvert映射接口中,通过@Mapping的qualifiedByName指定名为convertCreateTime的@Named方法转换createTime字段,编译时抛出异常:
java: Qualifier error. No method found annotated with @Named#value: [ convertCreateTime ]
相关代码如下:
@Mapper public interface UndoIssueConvert { UndoIssueConvert INSTANCE = Mappers.getMapper(UndoIssueConvert.class); @Mappings({ @Mapping(target = "undoIssueId", source = "id"), // @Mapping(target = "createTime", expression = ("java(undoIssue.getUpdateTime() != null ? undoIssue.getUpdateTime() : undoIssue.getCreateTime())")) @Mapping(target = "createTime", qualifiedByName = "convertCreateTime") }) UndoIssuePanelRspVO.UndoIssue toUndoIssue(UndoIssue undoIssue); List<UndoIssuePanelRspVO.UndoIssue> toUndoIssue(List<UndoIssue> undoIssue); @Named("convertCreateTime") default Date convertCreateTime(UndoIssue undoIssue) { return undoIssue.getUpdateTime() != null ? undoIssue.getUpdateTime() : undoIssue.getCreateTime(); } UndoIssue toUndoIssueEntity(UndoIssueAddUpdateVO addVO); }
问题原因
MapStruct匹配qualifiedByName对应的方法时,会严格校验方法的参数类型与映射时传递的参数是否一致。
你当前的@Mapping未指定source,MapStruct默认会尝试从源对象UndoIssue中取出createTime属性(Date类型)作为参数传递给转换器,但你的convertCreateTime方法接收的是整个UndoIssue对象,参数类型不匹配,因此找不到对应的方法。
解决办法
方案一:指定source为整个源对象
修改@Mapping的source为.(代表整个源对象实例),让MapStruct把完整的UndoIssue对象传给convertCreateTime方法:
@Mappings({ @Mapping(target = "undoIssueId", source = "id"), @Mapping(target = "createTime", source = ".", qualifiedByName = "convertCreateTime") }) UndoIssuePanelRspVO.UndoIssue toUndoIssue(UndoIssue undoIssue);
方案二:调整转换器方法的参数类型
如果不需要整个源对象,可以修改convertCreateTime方法的参数为单个属性类型,适配MapStruct默认的属性传递逻辑:
@Named("convertCreateTime") default Date convertCreateTime(Date createTime, Date updateTime) { return updateTime != null ? updateTime : createTime; } // 映射时无需额外配置,MapStruct会自动匹配同名属性作为参数 @Mappings({ @Mapping(target = "undoIssueId", source = "id"), @Mapping(target = "createTime", qualifiedByName = "convertCreateTime") }) UndoIssuePanelRspVO.UndoIssue toUndoIssue(UndoIssue undoIssue);
验证
修改后重新编译,MapStruct会正确识别到convertCreateTime方法,编译通过。
内容的提问来源于stack exchange,提问作者Code White
相关产品推荐
相关产品推荐

