Why Hibernate sometimes ignores FetchMode.JOIN?
Asked Answered
G

1

13

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.

Gastrostomy answered 22/4, 2016 at 14:41 Comment(0)
L
13

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.

Leatriceleave answered 22/4, 2016 at 15:33 Comment(2)
Thank you! That was it: the Criteria API ignores @Fetch, but using Root.fetch() (which is JPA) I can achieve the same result.Gastrostomy
@GiovanniLovato Thank you for the hint, that Root.fetch achieves the same result - that was very helpful. I only have to add, that the resulting Fetch can be casted to Join for further use. See also this link: https://mcmap.net/q/176609/-using-the-jpa-criteria-api-can-you-do-a-fetch-join-that-results-in-only-one-joinNight

© 2022 - 2024 — McMap. All rights reserved.