jpa 为什么Hibernate惰性加载在Kotlin中的行为不同?

6pp0gazn  于 2023-02-09  发布在  Kotlin
关注(0)|答案(2)|浏览(125)

使用Java 11、Sping Boot 2.4.5和Hibernate 5.4.29进行@OneToOne实体Map的Here is a simple example
在Java实现中,延迟加载工作正常-仅加载Post实体:

select id, details_id from post

Here is the same code,它会生成以下SQL语句:

select id, details_id from post

select pd.id, p.id, p.details_id
from post_details pd
    left outer join post p on pd.id = p.details_id
where pd.id = ?

select p.id, p.details_id from post p
where p.details_id = ?

我不明白这里出了什么问题。Map是一样的,但是LAZY被忽略了。而且双向关联被加载了两次--每端一个SELECT。
解决方案更新
除了Lukes's解决方案之外,我还想指出一个Kotlin混淆:令人惊讶的是kotlin-jpa插件不足以使JPA/Hibernate正常工作。我们不得不配置kotlin-spring插件(all-open插件的 Package 器),并配置它使@Entity打开。这样,Hibernate最终可以创建允许延迟加载的代理。

ycl3bljg

ycl3bljg1#

这是由Kotlin类引起的。为了修复它,请执行以下操作:
build.gradle插件部分:

plugins {
    kotlin("plugin.spring") version <kotlinVersion>
    kotlin("plugin.jpa") version <kotlinVersion>
}

在文件的底部

allOpen {
    annotation("javax.persistence.Entity")
    annotation("javax.persistence.MappedSuperclass")
    annotation("javax.persistence.Embeddable")
}

这应该可以解决问题

jjhzyzn0

jjhzyzn02#

我还注意到,Kotlin作用域函数with()将执行类上延迟加载属性的快速加载。

@OneToMany(mappedBy = "book", cascade = [CascadeType.ALL], fetch = FetchType.LAZY, orphanRemoval = true)
open var chapters: MutableSet<Chapter> = mutableSetOf()

使用with()函数

with(bookRepository.findById(bookId)) {
  assertNotNull(this)
}

这些章节将被快速加载,而下面的章节则不会:

val book: Book? = bookRepository.findById(bookId)
assertNotNull(book)

相关问题