2016-04-22 3 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

Спасибо! Вот и все: API критериев игнорирует '@ Fetch', но используя' Root.fetch() '(который является JPA), я могу добиться того же результата. –

Смежные вопросы