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

Java 17中Mapstruct转换类到Record时编译报错求助

MapStruct转换Java Record时的编译错误排查与解决

问题背景

代码从Java 11迁移到Java 17后,使用MapStruct将带Lombok注解的SomeClass转换为Java 17的SomeRecord时出现编译错误。当前使用版本:mapstruct 1.5.2.Final、lombok 1.18.22、openjdk 17.0.4,且无法修改SomeClass为Record,已启用MapStruct+Lombok绑定。

相关代码

SomeRecord定义

public record SomeRecord(String a, String b, String c) {}

SomeClass定义

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class SomeClass{
  private String x;
  private String y;
  private String z;
}

Mapper接口定义

@Mapper(componentModel = "spring")
public interface Mapper {

  @Mapping(target = "c", source = "someClass.z", qualifiedByName = "mapperFunction")
  SomeRecord toSomeRecord(SomeClass someClass);

  @Named("mapperFunction")
  static String someTransformation(String s) {
    // implementation not relevant
  }
}

编译错误信息

  • 错误1:结果类型SomeRecord中存在未知属性'c',是否指'null'?
  • 错误2:SomeRecord没有可访问的无参构造方法

问题原因与解决方法

错误1:未知属性'c'

Java Record的组件名(定义时的参数名a/b/c)需要编译时保留参数名信息,MapStruct才能识别。如果编译未启用-parameters参数,MapStruct无法解析Record的组件,就会报未知属性错误。

解决:

  1. 编译时添加-parameters参数:
    • Maven配置(在pom.xml的maven-compiler-plugin中添加):
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.1</version>
          <configuration>
              <source>17</source>
              <target>17</target>
              <compilerArgs>
                  <arg>-parameters</arg>
              </compilerArgs>
          </configuration>
      </plugin>
      
    • Gradle配置:
      tasks.withType(JavaCompile) {
          options.compilerArgs.add("-parameters")
      }
      
  2. 确保Lombok与MapStruct的注解处理器顺序正确,避免Lombok处理后丢失参数信息。

错误2:无参构造方法问题

Java Record默认只有全参构造方法,没有无参构造。当前Mapper只映射了c,未对a和b做映射,MapStruct生成代码时无法匹配全参构造,会尝试寻找无参构造导致报错。

解决:
补充所有Record组件的映射规则,让MapStruct能正确调用全参构造:

@Mapper(componentModel = "spring")
public interface Mapper {

  @Mapping(target = "a", source = "someClass.x")
  @Mapping(target = "b", source = "someClass.y")
  @Mapping(target = "c", source = "someClass.z", qualifiedByName = "mapperFunction")
  SomeRecord toSomeRecord(SomeClass someClass);

  @Named("mapperFunction")
  static String someTransformation(String s) {
    // implementation not relevant
  }
}

若某些字段允许为空,可显式指定默认值:

@Mapping(target = "a", defaultValue = "")

额外注意:Lombok与MapStruct兼容性

确保注解处理器依赖配置正确,Maven中需指定处理器路径顺序:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.1</version>
    <configuration>
        <source>17</source>
        <target>17</target>
        <compilerArgs>
            <arg>-parameters</arg>
        </compilerArgs>
        <annotationProcessorPaths>
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>1.5.2.Final</version>
            </path>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.22</version>
            </path>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok-mapstruct-binding</artifactId>
                <version>0.2.0</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 04:37:03