我有一个@ManyToOne
关系的实体,我想用一个查询检索它,因此使用@Fetch(FetchMode.JOIN)
。有时Hibernate不尊重并发布N + 1 SELECT
s。 有时我的意思是,因为我不知道触发它的是什么,所以我可以在同一个类中针对不同的查询这种情况发生或不发生。
这是一个简化的实体,带有我使用的注释:
@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
的第一个选择,然后是所有SELECT
的N Department
s(考虑没有缓存)。
我发现了许多类似的问题,但他们的答案提出了解决方法,并没有解释为什么会发生这种情况。请避免建议使用延迟加载的答案:这不是我要求的。
答案 0 :(得分:8)
规则很简单:查询忽略了获取模式。当你编写一个查询时,你会告诉你什么是连接的,什么没有连接。
只有在使用for
等方法加载实体或者浏览其他实体图并加载其关联时,才会考虑获取模式。