Hibernate 6.2中Java Record作为@Embeddable在Spring Boot 3.1报错
Caused by: java.lang.IllegalAccessException: Can not set final java.lang.String field MyRecord.name to java.lang.String
...
## 解决方案 ### 1. 确保编译时保留方法参数名 Hibernate需要通过反射获取Record构造函数的参数名来匹配字段,因此必须确保编译时启用`-parameters`选项: - **Maven**:在`pom.xml`的`maven-compiler-plugin`中添加配置 ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <parameters>true</parameters> </configuration> </plugin>
- Gradle:在
build.gradle中设置java { options.parameters = true }
Spring Boot默认已开启该选项,但手动构建时需确认配置生效。
2. 强制Hibernate使用构造函数实例化
在application.properties/application.yml中添加配置,禁用强制使用setter的策略:
spring.jpa.properties.hibernate.use_getters_setters=false
该配置会让Hibernate优先使用构造函数实例化不可变类型(如Record),而非尝试调用setter修改final字段。
3. 明确实体类的字段访问策略
在实体类上添加@Access(AccessType.FIELD),指定Hibernate直接通过字段访问数据,避免触发不必要的setter逻辑:
@Entity(name = "MyEntity") @Access(AccessType.FIELD) public class MyEntity { @Id private Long id; @Embedded private MyRecord record; // 构造函数、getter等保持不变 }
4. 验证Record定义的正确性
确保@Embeddable修饰的Record是静态内部类(避免依赖外部类实例),且所有组件字段与持久化映射的字段名称完全匹配。
验证
完成上述配置后,重新执行save()操作,Hibernate将通过Record的构造函数实例化对象,不再尝试修改final字段,即可正常完成持久化。
内容的提问来源于stack exchange,提问作者twobiers
相关产品推荐
相关产品推荐

