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

Hibernate如何修改Kotlin类中val成员的值?

Hibernate为何能修改Kotlin实体类中val修饰的id字段?

核心原因:Kotlin JPA插件的适配处理 + Hibernate的运行时修改能力

你遇到的现象是两个技术点共同作用的结果:

  1. Kotlin JPA插件的字段修饰符调整
    你使用的org.jetbrains.kotlin.plugin.jpa插件会自动对JPA实体类做适配:

    • 它依赖并启用了all-open插件的功能,把@Entity注解标记的类设为open(哪怕你没显式声明),这是JPA框架对实体类的基础要求。
    • 针对带@Id+@GeneratedValue注解的val属性,插件会修改其幕后字段的修饰符:把Kotlinval默认生成的private final幕后字段,调整为非final,为Hibernate修改字段值开了口子。
  2. Hibernate的运行时字段修改机制
    调用em.persist(b)时,Hibernate需要为新生成的实体分配主键ID,它会通过两种方式修改ID字段:

    • 反射突破限制:利用Java反射API的AccessibleObject.setAccessible(true),绕开字段的final修饰符,直接修改字段值。
    • 字节码增强:在运行时动态修改实体类的字节码,移除字段的final修饰符,或者注入修改字段的逻辑。

额外验证提示

你可以查看编译后的Bar类字节码:

  • 编译后的id字段修饰符会是private而非private final(JPA插件的处理结果)。
  • 就算字段保留final修饰符,Hibernate的反射机制依然能强制修改其值(Java的final字段在运行时并非绝对不可修改)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 00:05:22