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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 16:53:09