我有一个具有 @ManyToOne
关系的实体,我想通过单个查询检索它,因此使用 @Fetch(FetchMode.JOIN)
。有时 Hibernate 不遵守这一点并发出 N+1 个 SELECT
。对于有时,我的意思是因为我不知道是什么触发了它,所以我遇到过在同一类中针对不同查询可能发生或不发生这种情况的情况。
这是一个带有我使用的注释的简化实体:
@Entity
public class Employee {
@ManyToOne
@Fetch(FetchMode.JOIN)
private Department department;
}
与
CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);
Root<Employee> root = criteriqQuery.from(Employee.class);
TypedQuery<Employee> typedQuery = entityManager.createQuery(criteriaQuery);
List<Employee> employees = typedQuery.getResultList();
我希望单个查询可以获取 Employee
及其 Department
,例如
select ... from Employee join Department on ...
相反,我得到所有 N 个 Employee
的第一个选择,然后是所有 Department
的 N 个 SELECT
(考虑没有缓存)。
我发现了很多类似的问题,但他们的回答提出了解决方法,但没有解释为什么会这样。请避免建议使用延迟加载的答案:这不是我要问的。
最佳答案
规则很简单:查询忽略获取模式。当您编写查询时,您是在告诉什么已连接,什么未连接。
仅当使用 EntityManager.find(class, id)
等方法加载实体时,或在浏览其他实体图并加载其关联时,才会考虑获取模式。
关于java - 为什么 Hibernate 有时会忽略 FetchMode.JOIN?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36796798/