Ich versuche das zu tun:
%Vor% es erzeugt n + 1 Abfragen, wenn ich personRepository.findAll();
über ein Spring JPA-Repository mache, so als ob ich kein @Fetch
gesetzt hätte. (Eine Abfrage zuerst, um alle Personen zu erhalten, und dann eine Abfrage pro Person, um die Gruppen zu holen).
Die Verwendung von @Fetch(FetchMode.SUBSELECT)
funktioniert jedoch ! Es generiert nur 2 Abfragen. (Einer für alle Personen und dann einer für die Gruppen). Der Hibernate reagiert also auf einige Abrufparameter, nur nicht auf den JOIN
.
Ich habe auch versucht, das EAGER
fetching ohne Glück zu entfernen.
Ich verwende Spring JPA, und dies ist der Code für mein Repository:
%Vor%Arbeitet JOIN einfach nicht mit Spring JPA oder mache ich etwas falsch?
Gehen Sie durch viele Foren und Blogs, um nach Ihrem Problem zu lesen (ich nehme an, Sie haben das vielleicht getan, bevor Sie es hier gepostet haben). Ich denke auch, dass
@Fetch (FetchMode.JOIN) wird ignoriert, wenn Sie die Query-Schnittstelle verwenden (z. B. session.createQuery ()), aber es wird ordnungsgemäß verwendet, wenn Sie verwenden die Kriterienschnittstelle.
Dies ist praktisch ein Fehler in Hibernate, der nie gelöst wurde. Es ist bedauerlich, da viele Anwendungen die Query-Schnittstelle verwenden und kann nicht einfach auf die Kriterienschnittstelle migriert werden.
Wenn Sie die Query-Schnittstelle verwenden, müssen Sie immer JOIN FETCH hinzufügen Anweisungen in den HQL manuell.
Referenzen Hibernate Forum Spring Forum Ähnliche Frage 1
Ich konnte auch @Fetch(FetchMode.JOIN)
nicht verwenden, wenn ich JPA benutze (obwohl es gut funktioniert, wenn ich den Hibernate Criteria API benutze) und ich konnte auch keine Beispiele finden, die erklären warum, aber ich kann an einige Problemumgehungen denken.
Der einfachste Weg, um die Gruppen eifrig zu laden, ist die Verwendung von JPQL:
%Vor% Da Sie spring-data-jpa verwenden, können Sie die Gruppen auch gerne mit einem Specification
laden. (Ab 1.4.x können Sie Spezifikationen ketten, die null zurückgeben).
Wenn keine dieser Optionen für Sie geeignet ist, verwenden Sie am besten @Fetch(FetchMode.SUBSELECT)
.
Eine andere Option ist die Verwendung von @Fetch(FetchMode.SELECT)
in Kombination mit @BatchSize
. @BatchSize
hilft, das Problem der n + 1 Abfragen zu lösen. Durch Anpassen der Stapelgröße können Sie die Anzahl der Abfragen reduzieren, die an CEIL (n / batch_size) +1 ausgeführt werden.
Diese Zuordnung führt zu der folgenden SQL, wenn Sie personRepository.findAll();
in einer Datenbank mit 10 Personen und @BatchSize
auf 5 setzen.
Beachten Sie, dass @BatchSize
auch für Sammlungen funktioniert, die mit FetchType.LAZY
zugeordnet sind.
Tags und Links java jpa hibernate spring spring-data