无需调用属性即可获取n + 1的休眠惰性关系-Kotlin

时间:2018-10-09 14:18:04

标签: postgresql hibernate spring-boot jpa kotlin

我正在使用休眠并做一个简单的查询来选择所有给定的实体。我只想要实体,而不想要它的关系。但是,休眠确实会以n + 1的方式获取关系和关系。

这是一个用Kotlin编写的Spring Boot应用程序。

使用FetchType.LAZY注释关系,我正在执行的查询如下所示:

entityManager.createQuery("SELECT a FROM Apartment a")
    .resultList

这是我正在调用的唯一代码,我什至没有从控制器返回结果,因此,不是一些序列化库调用了惰性属性。

这些是实体:

@Entity
class Apartment(
        @Id
        private val id: String,
        private val heading: String,
        @ManyToOne(fetch = LAZY)
        private val building: Building
)

@Entity
class Building(
        @Id
        private val id: String,
        private val heading: String,
        @ManyToOne(fetch = FetchType.LAZY)
        private val owner: User
)

@Entity
@Table(name="users")
class User(
        @Id
        private val id: String,
        private val email: String
)

我打开了休眠查询日志记录,当我在上面运行查询时,它看起来像:

Fetch all apartments
Fetch buildings for apartment 1
Fetch users for building 1
fetch buildings for apartment 2
fetch users for building 2
....

我创建了一个可重现该问题的git存储库:https://github.com/Herlevsen/hibernate-lazy-fetch-repoduction

它带有一个docker-compose文件的安装程序,该文件会启动一个postgres数据库,并且该应用程序会在启动时自动创建架构并创建一些虚拟数据。因此,启动和运行相当容易。

我真的希望有人能告诉我发生了什么事。

谢谢!

1 个答案:

答案 0 :(得分:1)

您必须open实体类。 Hibernate需要open类来创建代理以支持LAZY-ManyToOne字段:

@Entity
open class Apartment(
    @Id
    private val id: String,
    private val heading: String,
    @ManyToOne(fetch = LAZY)
    private val building: Building
)

@Entity
open class Building(
    @Id
    private val id: String,
    private val heading: String,
    @ManyToOne(fetch = FetchType.LAZY)
    private val owner: User
)

@Entity
@Table(name="users")
open class User(
    @Id
    private val id: String,
    private val email: String
)

您也可以使用all-open-Plugin