首页 > 解决方案 > Spring Data JPA / Hibernate:在同一张表中使用JOIN列时如何避免不必要的JOIN

问题描述

让我们假设以下关联:

 @JoinColumn(
        name = "contract_id", nullable = false,
        foreignKey = ForeignKey(name = "fk_example__contract"),
 )
 val contract: Contract,

在一个名为Example

如果我查询 contract.id,Spring Data JPA 和 Hibernate 将创建 JOIN 到表 contract,即使列 contract_id 在同一个表中example

fun findAllByContractId(contractId: Long, pageable: Pageable): Page<ExampleProjection>

与 Criteria API 的效果相同

我们可以通过添加以下映射来避免不必要的 JOIN:

//avoiding join to contract, if just using ```contract_id``` in where clause
@Column(name = "contract_id", insertable = false, updatable = false)
var contractId: Long? = null 

添加此附加映射后,表的 LEFT OUTER JOINcontract在使用时消失findAllByContractId

此解决方案在我的测试用例中有一个缺点:在使用 repsitory.getOne(id) (Spring Data JPA)加载实体后,contractId实体中的属性为空。Example

contractId如果我只需要使用投影或者我只想在 where 子句中使用它,是否有更好的方法来避免连接,如果contract_id在同一个表中example

标签: hibernatejoinspring-data-jpa

解决方案


您如何定义它的列应该可以正常工作。

也许这是您如何使用repository.getOne() 加载数据的问题。你在测试中使用它吗?也许您需要调用testEntityManager.clear()以便 Hibernate 可以正确地将 id 列映射到您的实体属性


推荐阅读