You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mapstruct多源映射报错:目标类型无anotherObj读取访问器排查

MapStruct映射报错:No read accessor found for property anotherObj的解决办法

问题场景

我尝试用MapStruct实现Source与Target对象的映射,相关实体类代码如下:

@Data
@Builder
@Getter
public class Source {
    public String str3;
}

@Data
@Builder
@Getter
public class Target {
  public String str1;
  public String str2;
  public AnotherObj anotherObj;
}

@Data
@Builder
@Getter
public class AnotherObj {
  public String str3;
  public String str4;
}

编写的映射器代码:

@Mapping(target = "anotherObj", source = "request", qualifiedByName = "mapAnotherObjToSource")
@Mapping(target = "anotherObj.str4", source = "str4")
Target convert(Source request, String str4);

运行时出现错误:Java: No read accessor found for property anotherObj in target type.,我已经定义了Getter方法,尝试用@AfterMapping处理仍有问题:

@AfterMapping
default void handleStr4(@MappingTarget Target target, Source source, String str4) {
if (target.getAnotherObj() != null) {
    target.getCardMetadataInfo().setStr4(str4);
    }
}

错误原因分析

  1. 注解冗余冲突:实体类同时使用@Data和@Getter,@Data已包含@Getter、@Setter等注解,重复注解可能导致MapStruct对访问器的识别异常。
  2. 映射逻辑冲突:在映射器中同时指定了anotherObj的整体映射和其属性anotherObj.str4的单独映射,MapStruct处理嵌套映射时逻辑冲突,无法正确识别访问器。
  3. @AfterMapping笔误:代码中调用了不存在的getCardMetadataInfo()方法,应为getAnotherObj()。
  4. Builder模式影响:@Builder生成的实例默认通过Builder创建,可能导致MapStruct无法正确使用@Data生成的Setter方法操作嵌套对象。

解决方案

1. 清理冗余注解

去掉实体类中重复的@Getter,保留@Data和@Builder即可:

@Data
@Builder
public class Source {
    public String str3;
}

@Data
@Builder
public class Target {
  public String str1;
  public String str2;
  public AnotherObj anotherObj;
}

@Data
@Builder
public class AnotherObj {
  public String str3;
  public String str4;
}

2. 实现缺失的映射方法

确保mapAnotherObjToSource方法已正确定义,用于将Source转换为AnotherObj:

@Named("mapAnotherObjToSource")
default AnotherObj mapAnotherObjToSource(Source source) {
    return AnotherObj.builder()
            .str3(source.getStr3())
            .build();
}

3. 调整映射器配置(二选一)

方案一:用@AfterMapping处理嵌套属性赋值

去掉冲突的anotherObj.str4映射,通过@AfterMapping正确赋值:

@Mapping(target = "anotherObj", source = "request", qualifiedByName = "mapAnotherObjToSource")
Target convert(Source request, String str4);

@AfterMapping
default void handleStr4(@MappingTarget Target target, String str4) {
    if (target.getAnotherObj() != null) {
        target.getAnotherObj().setStr4(str4);
    }
}

方案二:在嵌套映射方法中直接传入str4

修改映射逻辑,在转换AnotherObj时直接使用str4参数,避免冲突:

@Mapping(target = "anotherObj", source = ".", qualifiedByName = "mapAnotherObjToSource")
Target convert(Source request, @Context String str4);

@Named("mapAnotherObjToSource")
default AnotherObj mapAnotherObjToSource(Source source, @Context String str4) {
    return AnotherObj.builder()
            .str3(source.getStr3())
            .str4(str4)
            .build();
}

4. 确保MapStruct配置正确

检查maven/gradle的注解处理器配置,确保MapStruct能正常生成映射实现类,例如maven配置:

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.5.5.Final</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.5.5.Final</version>
    <scope>provided</scope>
</dependency>

内容的提问来源于stack exchange,提问作者Pavanraotk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 13:23:37