Ich habe eine Order
Klasse mit einer Liste von OrderTransactions
und habe sie mit einer Eins-zu-Viele-Zuordnung im Ruhezustand wie folgt zugeordnet:
@OneToMany(targetEntity = OrderTransaction.class, cascade = CascadeType.ALL)
public List<OrderTransaction> getOrderTransactions() {
return orderTransactions;
}
Diese Order
haben auch ein Feld orderStatus
, das zum Filtern mit den folgenden Kriterien verwendet wird:
public List<Order> getOrderForProduct(OrderFilter orderFilter) {
Criteria criteria = getHibernateSession()
.createCriteria(Order.class)
.add(Restrictions.in("orderStatus", orderFilter.getStatusesToShow()));
return criteria.list();
}
Dies funktioniert und das Ergebnis ist wie erwartet.
Nun , hier ist meine Frage : Warum, wenn ich die Art holen gesetzt explizit auf EAGER
, tut die Order
s mehrfach in der Ergebnisliste erscheinen?
@OneToMany(targetEntity = OrderTransaction.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
public List<OrderTransaction> getOrderTransactions() {
return orderTransactions;
}
Wie müsste ich meinen Kriteriencode ändern, um mit der neuen Einstellung das gleiche Ergebnis zu erzielen?
Antworten:
Dies ist tatsächlich das erwartete Verhalten, wenn ich Ihre Konfiguration richtig verstanden habe.
Sie erhalten dieselbe
Order
Instanz in jedem der Ergebnisse, aber da Sie jetzt einen Join mit dem durchführenOrderTransaction
, muss dieselbe Anzahl von Ergebnissen zurückgegeben werden, die ein regulärer SQL-Join zurückgibtEigentlich sollte es also mehrmals auftauchen. Dies wird vom Autor (Gavin King) selbst hier sehr gut erklärt: Es erklärt sowohl warum als auch wie man immer noch eindeutige Ergebnisse erzielt
Auch in den FAQ zum Ruhezustand erwähnt :
quelle
Zusätzlich zu dem, was Eran erwähnt, besteht eine andere Möglichkeit, das gewünschte Verhalten zu erzielen, darin, den Ergebnis-Transformator einzustellen:
quelle
Versuchen
beispielsweise
}}
quelle
Verwenden Sie nicht List und ArrayList, sondern Set und HashSet.
quelle
Mit Java 8 und Streams füge ich meiner Dienstprogrammmethode diese Rückgabeanweisung hinzu:
Streams entfernen Duplikate sehr schnell. Ich verwende Anmerkungen in meiner Entitätsklasse wie folgt:
Ich denke, es ist besser in meiner App, eine Sitzung in einer Methode zu verwenden, bei der ich Daten aus der Datenbank benötige. Abschlusssitzung, wenn ich fertig bin. Natürlich habe ich meine Entity-Klasse so eingestellt, dass sie den Leasy-Fetch-Typ verwendet. Ich gehe zum Refactor.
quelle
Ich habe das gleiche Problem beim Abrufen von 2 zugeordneten Sammlungen: Benutzer hat 2 Rollen (Set) und 2 Mahlzeiten (Liste) und Mahlzeiten werden dupliziert.
DISTINCT hilft nicht (DATA-JPA-Abfrage):
Endlich habe ich 2 Lösungen gefunden:
Endgültige Lösung:
quelle
Anstatt Hacks wie:
Set
anstattList
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
die Ihre SQL-Abfrage nicht ändern, können wir verwenden (unter Angabe von JPA-Spezifikationen)
Dadurch wird die resultierende SQL-Abfrage geändert, sodass ein
DISTINCT
darin enthalten ist.quelle
Es klingt nicht nach einem großartigen Verhalten, einen äußeren Join anzuwenden und doppelte Ergebnisse zu erzielen. Die einzige verbleibende Lösung besteht darin, unser Ergebnis mithilfe von Streams zu filtern. Dank Java8 gibt es eine einfachere Möglichkeit zum Filtern.
quelle