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的组件,就会报未知属性错误。
解决:
- 编译时添加
-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") }
- Maven配置(在
- 确保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
相关产品推荐
相关产品推荐

