我有一个带有@ManyToOne关系的实体,我想通过一个查询来检索它,因此使用@Fetch(FetchMode.JOIN)。有时,Hibernate不尊重它,而是发出N + 1 SELECT秒。随着 有时 我的意思是,因为我不知道是什么触发它,我有案件对不同的查询,这可能发生,或者不一样的类。
@ManyToOne
@Fetch(FetchMode.JOIN)
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,例如
Employee
Department
select ... from Employee join Department on ...
相反,我得到了第一选择所有N EmployeeS和那么N SELECT献给所有DepartmentS(考虑没有缓存)。
我发现了许多类似的问题,但是他们的回答提出了解决方法,但没有解释为什么会这样。请避免出现建议使用延迟加载的答案:这不是我要的。
规则很简单:查询会忽略获取模式。当您编写查询时,您在说什么已联接和什么未联接。
仅当实体使用类似方法加载时,EntityManager.find(class, id)或在其他实体图中导航并加载其关联时,才考虑使用提取模式。
EntityManager.find(class, id)