Wir haben ein n + 1 Problem mit Hibernate 3.3.
Der Einfachheit halber mache ich nur ein kurzes abstraktes Beispiel.
Angenommen, wir haben die folgenden einfachen Klassen:
%Vor% Wie Sie sehen können, hat SubEntity
eine Beziehung zu MainEntity
, die durch zwei Eigenschaften ausgedrückt wird, wobei die Eigenschaft mainId
für die Verwaltung der Beziehung / des Fremdschlüssels verantwortlich ist.
Das funktioniert ganz gut und passt perfekt zu unseren Bedürfnissen.
Allerdings gibt es ein Problem, wenn wir das SubEntity
zusammen mit dem MainEntity
gerne laden.
Angenommen, ich habe eine Abfrage, die eine Sammlung von MainEntity
zurückgibt. Mit dem aktuellen Setup gibt Hibernate n + 1 selects aus: Die Abfrage selbst + n wählt für jedes SubEntity
aus.
Natürlich könnte ich der Abfrage einen join fetch
hinzufügen, aber ich möchte lieber, dass Hibernate das automatisch macht. Also habe ich versucht, @Fetch( FetchMode.JOIN )
hinzuzufügen, aber das hat nichts bewirkt.
Ich hätte auch kein Problem mit @Fetch( FetchMode.SUBSELECT )
, was die Select-Anweisungen auf 2 reduzieren würde - die ursprüngliche Abfrage und eine Auswahl für die Sub-Entitäten (zumindest passiert das auf einer anderen Eigenschaft mit @CollectionOfElements
und% co_de) %).
Die Frage ist also: Wie würde ich Hibernate sagen, dass automatisch fetch beitreten oder eine einzelne Auswahl verwenden soll, um die Sub-Entitäten eifrig zu laden? Fehle ich etwas?
Vielen Dank im Voraus,
Thomas
PS: Eine Sache, die ein Problem sein könnte, könnte die @Fetch( FetchMode.SUBSELECT )
sein, die nicht auf die tatsächliche ID-Spalte verweist, aber ich kann sie nicht in mappedBy = "main"
ändern.
Wenn Sie Primärschlüssel zwischen MainEntity und SubEntity freigeben möchten, verwenden Sie PrimaryKeyJoinColumn
und MapsId
Annotation.
Mit PrimaryKeyJoinColumn
wird die Entity geladen
indem Sie die Tabelle MainEntity
mit der Tabelle SubEntity
mit demselben Primärschlüssel verknüpfen. Es sollte die n + 1 Probleme lösen.
Die MapsId
Annotation bittet Hibernate, den Identifier zu kopieren
Eine andere assoziierte Entität in unserem Beispiel kopiert die SubEntity.mainEntity.id
nach SubEntity.id
.
Hibernate-Referenzdokumentation: