Warum feuert JPA / Eclipselink redundante Datenbankabfragen auch mit dem Hinweis BatchFetchType.IN?

8

Zusammenfassung:

Ich versuche, die Anzahl der Abfragen zu minimieren, die meine JPA-basierte Java-Anwendung in der Datenbank macht. Ich habe den @BatchFetch(BatchFetchType.IN) Optimierungshinweis angegeben, aber ich sehe immer noch einige zusätzliche Abfragen, die ich für überflüssig und unnötig halten würde.

Details:

Betrachten wir ein einfaches Domain-Modell: Wir haben Invoice mgmt system. Rechnung hat OneToOne-Beziehung mit Bestellung. Wir haben auch Kunden, die eine OneToMany-Beziehung zu Bestellungen haben. (Kunde 1- & g; M Bestellung 1 & lt; -1 Rechnung) . Mehr Details finden Sie hier . . Hier finden Sie den vollständigen Quellcode . Hier ist die Entitätsdefinition, wie sie derzeit steht:

Client.java (außer Getter und Setter ):

%Vor%

Order.java (außer Getter und Setter ):

%Vor%

Invoice.java (Ausschließlich Getter und Setter ):

%Vor%

Mit diesem Modell habe ich einen einfachen Test durchgeführt, um alle Bestellungen eines Kunden abzurufen.

%Vor%

Da alles faul abgerufen wurde, haben wir vier Abfragen, wie gezeigt:

%Vor%

Da ich keine N + 1-Aufrufe zum Abrufen von Rechnungen haben möchte, dachte ich, Batch-Abruf zu verwenden und die Gesamtzahl der Abfragen auf 4 zu reduzieren (Eine Abfrage, um Rechnungen für alle Bestellungen des Kunden abzurufen). Um das Gleiche zu tun, habe ich meine Order-Entity wie folgt aktualisiert:

Aktualisiert - Order.java, BatchFetch für Rechnung hinzufügen. (Außer Getter und Setter ):

%Vor%

Ich habe den gleichen Test erneut ausgeführt und ging davon aus, dass es drei Abfragen zum Abrufen der Daten geben wird (eine für Kunden, eine für Bestellungen und eine für das Stapeln von Rechnungen). Allerdings Eclipselink generiert 5 Abfragen für dasselbe. Hier sind die Fragen:

%Vor%

Ich habe nicht verstanden, warum die letzten zwei Abfragen generiert werden. Jede Hilfe, um zu erklären, was vor sich geht, wäre hilfreich.

Danke!

    
Rahul Tanwani 30.04.2014, 18:42
quelle

1 Antwort

12

Sieht in EclipseLink wie ein Fehler / Problem aus, da die begierigen Beziehungen im Objektmodell durchlaufen werden, so dass die zweite Rechnung im "in" geladen werden kann, bevor die Bestellung, auf die sie verweist, geladen wird. Dadurch wird die Rechnung gezwungen, die Bestellung in der Datenbank abzufragen, anstatt sie im Cache zu finden.

Sie können das Problem beheben, indem Sie in der Beziehung Rechnung zu Bestellung einen verzögerten Abruf verwenden. Diese Verzögerung ermöglicht es EclipseLink, das Objektmodell vollständig zu erstellen, sodass es beim Zugriff auf den Cache verbleibt. Der Code in der Frage zeigt, dass diese Beziehung als "Lazy" markiert ist. Dies ist jedoch nur ein Hinweis für JPA-Provider, die in EclipseLink nicht wie hier beschrieben mit einem Agenten- oder Bytecode-Weben arbeiten können: Ссылка Ссылка

Weben ist nicht erforderlich für faule Sammlungen, nur für 1: 1 und andere Optimierungen.

    
Chris 07.05.2014, 17:23
quelle