Hibernate如何更改kotlin类中的val?

wgxvkvu9  于 2022-11-24  发布在  Kotlin
关注(0)|答案(1)|浏览(178)

在下面的代码中,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所示

jchrr9hc

jchrr9hc1#

如果您使用javap反汇编已编译的类Bar,您将看到签名为:

public final class foo.Bar {
   private final int v;
   private final java.util.UUID id;
   public foo.Bar(int);
   public foo.Bar(int, int, kotlin.jvm.internal.DefaultConstructorMarker);
   public final int getV();
   public final java.util.UUID getId();
   public foo.Bar();
}

...所以你对生成的类的假设是正确的。但是final字段没有通过反射来防止修改,所以Hibernate无论如何都可以更改id字段的值...
如果在java.lang.reflect.Field.set(Object obj, Object value)方法中设置断点,并使用调试器运行测试,您将看到Hibernate使用的调用和访问路径...

相关问题