Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
409 views
in Technique[技术] by (71.8m points)

java - 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). Sometimes Hibernate doesn't respect that and issues N+1 SELECTs. 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

select ... from Employee join Department on ...

instead I get a first select for all N Employees and then N SELECTs for all Departments (consider no cache).

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...