2016-04-22 26 views
3

Ich habe eine Entität mit einer @ManyToOne Beziehung, die ich mit einer einzigen Abfrage abrufen möchte, also @Fetch(FetchMode.JOIN) verwenden. Manchmal respektiert Hibernate das nicht und gibt N + 1 SELECT s aus. Mit manchmal ich meine, da ich nicht weiß, was es auslöst, habe ich Fälle, die auf der gleichen Klasse für verschiedene Abfragen dies passieren können oder nicht.Warum ignoriert Hibernate manchmal FetchMode.JOIN?

Dies ist eine vereinfachte Einheit mit den Anmerkungen Ich benutze:

@Entity 
public class Employee { 

    @ManyToOne 
    @Fetch(FetchMode.JOIN) 
    private Department department; 

} 

Mit

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(); 

würde ich eine einzelne Abfrage erwarten sowohl Employee und seine Department, so etwas wie

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

stattdessen bekomme ich eine erste Auswahl für alle N Employee s und dann N SELECT s für alle Department s (keinen Cache berücksichtigen).

Ich habe viele ähnliche Fragen gefunden, aber ihre Antworten schlagen Workarounds vor und erklären nicht, warum dies geschieht. Bitte vermeiden Sie Antworten, die darauf hindeuten, dass Sie lazy loading verwenden: Es ist nicht das, was ich frage.

Antwort

5

Die Regel ist ziemlich einfach: Abfragen ignorieren Abrufmodi. Wenn Sie eine Abfrage schreiben, sagen Sie, was verbunden ist und was nicht verbunden ist.

Der Abrufmodus wird nur berücksichtigt, wenn die Entität mit Methoden wie EntityManager.find(class, id) oder beim Navigieren durch ein anderes Entitätsdiagramm und Laden von Zuordnungen geladen wird.

+0

Vielen Dank! Das war es: Die Kriterien-API ignoriert '@ Fetch', aber mit' Root.fetch() '(was JPA ist) kann ich das gleiche Ergebnis erzielen. –

Verwandte Themen