如何在MapStruct中配置映射以获取Child DTO中的Parent字段?
MapStruct 子类转DTO时继承字段映射解决方案
现有代码结构
public class Parent { String parentField; // 默认包私有访问权限 } public class Child extends Parent { } public class ChildDTO { String parentField; } @Mapper(componentModel = "spring") public interface ChildMapper { ChildDTO toDTO(Child child); }
需求
配置MapStruct映射,让ChildDTO能够获取Parent类中的parentField字段值。
已尝试的写法
写法一
@Mapper(componentModel = "spring") public interface ChildMapper { @Mapping(source = "parentField", target = "parentField") ChildDTO toDTO(Child child); }
写法二
@Mapper(componentModel = "spring") public interface ChildMapper { @Mapping(source = "parentField", target = "parentField", qualifiedByName = "mapParentField") ChildDTO toDTO(Child child); @Named("mapParentField") default String mapParentField(Parent parent) { return parent.getParentField(); } }
正确配置方案
问题核心在于父类Parent的parentField是包私有访问权限,且未提供公共getter方法,MapStruct无法直接读取该字段值。解决步骤如下:
- 给
Parent类添加parentField的公共getter方法:
public class Parent { String parentField; // 添加公共getter,让MapStruct可以访问字段 public String getParentField() { return parentField; } // 可选:若需要设置字段值,添加setter public void setParentField(String parentField) { this.parentField = parentField; } }
- 简化Mapper接口,无需额外
@Mapping注解(字段名完全匹配时,MapStruct会自动识别父类继承的字段):
@Mapper(componentModel = "spring") public interface ChildMapper { ChildDTO toDTO(Child child); }
如果需要显式声明映射关系(比如字段名不一致场景),也可以保留@Mapping,前提是父类字段有可访问的getter:
@Mapper(componentModel = "spring") public interface ChildMapper { @Mapping(source = "parentField", target = "parentField") ChildDTO toDTO(Child child); }
之前写法无效的原因
- 写法一中,
Parent的parentField无getter,MapStruct无法读取字段值,生成的映射代码不会处理该字段。 - 写法二中,
@Mapping的source指向Child实例的parentField,但默认方法参数是Parent,MapStruct无法匹配参数,导致映射逻辑不生效。
内容的提问来源于stack exchange,提问作者Evgen Kr
相关产品推荐
相关产品推荐

