在下面的代码中,Hibernate如何更改val
成员id
的值?即使对该对象的引用是val
,我也无法看到如何替换不同的对象。
import jakarta.persistence.*
import java.util.UUID
@Entity
class Bar (val v: Int = 0) {
@Id @GeneratedValue @Column(columnDefinition="UUID default gen_random_uuid()")
val id = UUID.fromString("00000000-0000-0000-0000-000000000000")
}
fun main () {
val emf = HibernatePersistenceProvider().createContainerEntityManagerFactory(
MyPersistenceUnitInfo(), Properties()
)
emf.createEntityManager().let { em ->
em.transaction.begin()
val b = Bar(7)
println(b.id) // prints 00000000-0000-0000-0000-000000000000
em.persist(b)
println(b.id) // prints 82a7bc5a-f92d-4d7f-872a-3eb3ba7a5541
em.transaction.commit()
em.close()
}
}
我确实在我的build.gradle.kts
中使用了JPA插件,如下所示:
plugins {
kotlin("jvm") version "latest.release"
kotlin("plugin.serialization") version "latest.release"
id("com.google.cloud.tools.jib") version "latest.release"
id("com.google.cloud.artifactregistry.gradle-plugin") version "latest.release"
id("org.jetbrains.kotlin.plugin.jpa") version "latest.release"
application
}
但我没有使用“所有开放”插件,如果这很重要的话。
最后,我仍然感到困惑,val b
中的val id
引用如何由于em.persist(b)
调用而发生变化,如两个println
所示
1条答案
按热度按时间jchrr9hc1#
如果您使用javap反汇编已编译的类
Bar
,您将看到签名为:...所以你对生成的类的假设是正确的。但是
final
字段没有通过反射来防止修改,所以Hibernate无论如何都可以更改id
字段的值...如果在
java.lang.reflect.Field.set(Object obj, Object value)
方法中设置断点,并使用调试器运行测试,您将看到Hibernate使用的调用和访问路径...