[英]Why Hibernate sometimes ignores FetchMode.JOIN?
I have an entity with a @ManyToOne
relation, which I'd like to retrieve with a single query, thus using @Fetch(FetchMode.JOIN)
. 我有一个具有
@ManyToOne
关系的实体,我想用单个查询检索它,因此使用@Fetch(FetchMode.JOIN)
。 Sometimes Hibernate doesn't respect that and issues N+1 SELECT
s. 有时Hibernate不尊重并发布N + 1
SELECT
。 With sometimes I mean that since I don't know what triggers it, I have cases which on the same class for different queries this could happen or not. 有时我的意思是,因为我不知道触发它的是什么,所以我可以在同一个类中针对不同的查询这种情况发生或不发生。
This is a simplified entity with the annotations I use: 这是一个带有我使用的注释的简化实体:
@Entity
public class Employee {
@ManyToOne
@Fetch(FetchMode.JOIN)
private Department department;
}
With 同
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();
I would expect a single query to fetch both Employee
and its Department
, something like 我希望单个查询可以获取
Employee
及其Department
,例如
select ... from Employee join Department on ...
instead I get a first select for all N Employee
s and then N SELECT
s for all Department
s (consider no cache). 相反,我得到所有N
Employee
第一个选择,然后是所有Department
的N SELECT
(考虑没有缓存)。
I've found many similar questions, but their answers suggest workarounds and do not explain why this is happening. 我发现了许多类似的问题,但他们的答案提出了解决方法,并没有解释为什么会发生这种情况。 Please, avoid answers suggesting to use lazy loading: it's not what I'm asking.
请避免建议使用延迟加载的答案:这不是我问的问题。
The rule is quite simple: Queries ignore fetch modes. 规则很简单:查询忽略了获取模式。 When you write a query, you are telling what is joined and what is not joined.
当您编写查询时,您将告知已加入的内容和未加入的内容。
Fetch mode is only taken into account when entity is loaded with methods like EntityManager.find(class, id)
or when navigating through some other entity graph and loading its associations. 仅当实体加载了
EntityManager.find(class, id)
或者导航通过其他实体图并加载其关联时EntityManager.find(class, id)
才会考虑获取模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.