2016-04-22 187 views
3

我有一个@ManyToOne关系的实体,我想用一个查询检索,因此使用@Fetch(FetchMode.JOIN)。有时Hibernate不尊重并且发布N + 1 SELECT s。 有时我的意思是,因为我不知道是什么触发它,我有案件在同一类不同的查询这可能发生与否。为什么Hibernate有时会忽略FetchMode.JOIN?

这是我使用的注释简化实体:

@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 s,然后N SELECT s对所有Department s(考虑无缓存)。

我发现了很多类似的问题,但他们的答案提示了解决方法,并没有解释为什么会发生这种情况。请避免提示使用延迟加载的答案:这不是我要求的。

回答

5

规则很简单:查询忽略提取模式。当你写一个查询时,你告诉什么是加入的,什么是未加入的。

只有当实体加载了像EntityManager.find(class, id)这样的方法时,或者在浏览某个其他实体图并加载其关联时,才会考虑提取模式。

+0

谢谢!就是这样:Criteria API忽略'@ Fetch',但使用'Root.fetch()'(这是JPA)我可以达到相同的结果。 –