为什么Hibernate有时会忽略FetchMode.JOIN?

时间:2016-04-22 14:41:12

标签: java hibernate jpa optimization

我有一个@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(考虑没有缓存)。

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

1 个答案:

答案 0 :(得分:8)

规则很简单:查询忽略了获取模式。当你编写一个查询时,你会告诉你什么是连接的,什么没有连接。

只有在使用for等方法加载实体或者浏览其他实体图并加载其关联时,才会考虑获取模式。