Welchen Java-Typ verwenden Sie für JPA-Sammlungen und warum?

Lesezeit: 8 Minuten

Benutzer-Avatar
Das Ö

Welche der folgenden Sammlungstypen verwenden Sie in Ihrem JPA-Domänenmodell und warum:

  • java.util.Collection
  • java.util.List
  • java.util.Set

Ich habe mich gefragt, ob es dafür einige Grundregeln gibt.

AKTUALISIEREN Ich kenne den Unterschied zwischen a Set und ein List. EIN List erlaubt Duplikate und hat einen Auftrag und a Set darf keine doppelten Elemente enthalten und definiert keine Reihenfolge. Ich stelle diese Frage im Zusammenhang mit JPA. Wenn Sie sich strikt an die Definition halten, sollten Sie am Ende immer die verwenden Set Typ, da Ihre Sammlung in einer relationalen Datenbank gespeichert ist, wo Sie keine Duplikate haben können und wo Sie selbst eine Reihenfolge definieren müssen, dh die Reihenfolge in Ihrem Java List nicht unbedingt in der DB erhalten.

Zum Beispiel benutze ich meistens die List Typ, nicht weil es eine Reihenfolge hat oder Duplikate erlaubt (was ich sowieso nicht haben kann), weil einige der Komponenten in meiner Komponentenbibliothek eine Liste erfordern.

  • Ich glaube, Sie finden die Anmerkung @OrderBy vielleicht nützlich und interessant. Erster Link von Google dazu: objectdb.com/api/java/jpa/OrderBy

    – Grzegorz Oledzki

    11. Januar 2011 um 8:35 Uhr

  • @Grzegorz Oledzki Ich kenne das @OrderBy Anmerkung, aber es hat nichts mit der Reihenfolge in Ihrer zu tun List. Wenn Sie Ihre Entitätsliste abrufen (die mit kommentiert ist @OrderBy), seine Reihenfolge ändern, mit der DB zusammenführen und erneut abrufen, wird die geänderte Reihenfolge beibehalten? Nein! Sie erhalten dieselbe Reihenfolge, die Sie über definiert haben @OrderBy

    – Das Ö

    11. Januar 2011 um 8:46 Uhr

  • Ich stimme zu, das wäre großartig. Aber du bist schon auf halbem Weg. Wenn Sie eine solche Entität lesen, erhalten Sie die richtige Reihenfolge.

    – Grzegorz Oledzki

    11. Januar 2011 um 13:50 Uhr

  • Die Annotation @OrderColumn wird einer Reihenfolgenspalte in der Datenbank zugeordnet, die speziell verwendet wird, um die Reihenfolge von Elementen in einer Liste beizubehalten, wenn Sie sie im Speicher ändern. Nachteil: Das Ändern der Reihenfolge eines Elements führt zu Aktualisierungen potenziell aller Zeilen, um die Reihenfolgespalte zu aktualisieren und sie mit der Reihenfolge im Speicher konsistent zu halten.

    – Deutsch

    25. April 2013 um 17:41 Uhr

Benutzer-Avatar
Konrad Garus

Wie Ihre eigene Frage andeutet, Der Schlüssel ist die Domäne, nicht JPA. JPA ist nur ein Framework, das Sie so verwenden können (und sollten), wie es am besten zu Ihrem Problem passt. Die Wahl einer suboptimalen Lösung aufgrund des Frameworks (oder seiner Grenzen) ist normalerweise ein Warnsignal.

Wenn ich ein Set brauche und mir die Reihenfolge egal ist, verwende ich a Set. Wenn aus irgendeinem Grund die Reihenfolge wichtig ist (geordnete Liste, Sortierung nach Datum usw.), dann a List.

Sie scheinen sich des Unterschieds zwischen bewusst zu sein Collection, Setund List. Der einzige Grund, das eine gegen das andere zu verwenden, hängt nur von Ihren Bedürfnissen ab. Du kannst Verwenden Sie sie, um Benutzern Ihrer API (oder Ihrem zukünftigen Ich) die Eigenschaften Ihrer Sammlung mitzuteilen (was subtil oder implizit sein kann).

Dies folgt genau den gleichen Regeln wie die Verwendung unterschiedlicher Sammlungstypen an anderer Stelle in Ihrem Code. Du könntest benutzen Object oder Collections für alle Ihre Referenzen, aber in den meisten Fällen verwenden Sie konkretere Typen.

Wenn ich zum Beispiel ein sehe List, ich weiß, dass es irgendwie sortiert kommt und dass Duplikate für diesen Fall entweder akzeptabel oder irrelevant sind. Wenn ich ein sehe Seterwarte ich normalerweise, dass es keine Duplikate und keine bestimmte Reihenfolge hat (es sei denn, es ist eine SortedSet). Wenn ich ein sehe Collectionich erwarte nicht mehr davon, als einige Entitäten zu enthalten.

In Bezug auf die Listenreihenfolge … Ja, es kann beibehalten werden. Und selbst wenn es nicht so ist und Sie es einfach benutzen @OrderBy, es kann immer noch nützlich sein. Denken Sie an das Beispiel des standardmäßig nach Zeitstempel sortierten Ereignisprotokolls. Die Liste künstlich neu zu ordnen macht wenig Sinn, aber es kann trotzdem nützlich sein, dass sie standardmäßig sortiert kommt.

  • Sollten Sie nicht am Ende immer verwenden Set dann? Da Sie Ihre Entitäten in einer relationalen Datenbank speichern, in der es keine doppelten Elemente geben darf und in der Sie selbst eine Reihenfolge definieren müssen (dh die Reihenfolge in Ihrer Java List wird nicht beibehalten, wenn es beibehalten wird). Und wann verwenden Sie Collection?

    – Das Ö

    11. Januar 2011 um 8:11 Uhr


  • Bei Bedarf können Sie darauf bestehen List Auftrag mit einem künstlichen Feld. In den meisten Fällen ist es jedoch natürlich. Ein Beispiel kann eine Art zeitbasiertes Protokoll sein, in dem Sie @OrderBy(“eventDate”) verwenden können. Wie für Collectionich würde es in ähnlichen Situationen wie verwenden Set.

    – Konrad Garus

    11. Januar 2011 um 8:32 Uhr

  • Ja, Sie können eine Indexspalte oder die verwenden @OrderBy Anmerkung, aber diese so festgelegte Reihenfolge steht in keinem Zusammenhang mit der Reihenfolge in Ihrer Java-Liste. Sie können auch die verwenden @OrderBy Anmerkung zu a Set oder verwenden Sie eine Indexspalte. Und wenn Sie die Reihenfolge in Ihrer Java-Liste ändern, wird die Reihenfolge in der DB nicht in der DB widergespiegelt.

    – Das Ö

    11. Januar 2011 um 9:05 Uhr

  • Siehe aktualisierte Antwort. Kurz gesagt, befolgen Sie genau die gleichen Regeln, die Sie überall sonst in Ihrer Anwendung verwenden.

    – Konrad Garus

    11. Januar 2011 um 13:26 Uhr

  • Ein Fall, den ich gesehen habe, der das Wasser trübt, ist JSF. Es unterstützt nicht die Set-Schnittstelle für Entitätssammlungen, sondern nur List. Dies ist auf der Ansichtsseite in Ordnung, aber keine Speicherung (im Allgemeinen). Die Ansicht muss in diesem Fall also eine Liste sein, die leider ständig zum/vom Set übersetzt wird.

    – Darrell Teague

    10. März 2013 um 1:58 Uhr

Die Frage, ob man ein Set oder eine Liste verwendet, ist meiner Meinung nach viel schwieriger. Zumindest bei der Nutzung überwintern als JPA-Implementierung. Wenn Sie eine Liste im Ruhezustand verwenden, wechselt sie automatisch in den Ruhezustand “Taschen” Paradigma, bei dem Duplikate existieren KÖNNEN.

Und diese Entscheidung hat erheblichen Einfluss auf die Abfragen, die der Ruhezustand ausführt. Hier ein kleines Beispiel:

Es gibt zwei Entitäten, Angestellter und Gesellschaft, eine typische Viele-zu-Viele-Beziehung. Um diese Entitäten einander zuzuordnen, existiert eine JoinTable (nennen wir sie “employeeCompany”).

Sie wählen die Datentyp Liste auf beide Einheiten (Unternehmen/Mitarbeiter)

Also, wenn Sie sich jetzt dafür entscheiden Löschen Angestellter Jo aus Firma XYhibernate führt die folgenden Abfragen aus:

delete from employeeCompany where employeeId = Joe;
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXA);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXB);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXC);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXD);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXE);

Und jetzt die Frage: Warum zum Teufel führt Hibernate diese Abfrage nicht nur aus?

delete from employeeCompany where employeeId = Joe AND company = companyXY;

Die Antwort ist einfach (und vielen Dank an Nirav Assar für seinen Blogpost): Es kann nicht. In einer Welt der Taschen ist es der einzig richtige Weg, alle zu löschen und alle verbleibenden wieder einzufügen! Lesen Sie das für mehr Klarheit. http://assarconsulting.blogspot.fr/2009/08/why-hibernate-does-delete-all-then-re.html

Nun das große Fazit:

Wenn Sie in Ihren Mitarbeiter/Firma – Entitäten ein Set anstelle einer Liste wählen, haben Sie dieses Problem nicht und es wird nur eine Abfrage ausgeführt!

Und warum das? Denn Hibernate befindet sich nicht mehr in einer Welt der Taschen (wie Sie wissen, erlaubt Sets keine Duplikate) und es ist jetzt nur noch eine Abfrage möglich.

Die Entscheidung zwischen List und Sets ist also gar nicht so einfach, zumindest was Abfragen & Performance angeht!

Ich verwende im Allgemeinen eine Liste. Ich finde die List-API viel nützlicher und kompatibel mit anderen Bibliotheken als Set. List ist einfacher zu iterieren und im Allgemeinen effizienter für die meisten Operationen und Speicher.

Die Tatsache, dass eine Beziehung keine Duplikate haben kann und normalerweise nicht geordnet ist, sollte die Verwendung eines Satzes nicht erfordern, Sie können jeden Sammlungstyp verwenden, der für Ihre Anwendung am nützlichsten ist.

Es hängt jedoch von Ihrem Modell ab. Wenn Sie viele Contains-Prüfungen durchführen, wäre ein Set effizienter.

Sie können eine Beziehung in JPA entweder mit @OrderBy oder @OrderColumn bestellen.

Sehen,
http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Ordering

Duplikate werden in JPA im Allgemeinen nicht unterstützt, aber einige Zuordnungen wie ElementCollections unterstützen möglicherweise Duplikate.

Ich benutze:

  • Set: Wenn die Artikel in den Sammlungen keine Reihenfolge haben und einzigartig sind
  • Liste: wenn die Artikel eine Bestellung haben

https://issues.apache.org/jira/browse/OPENJPA-710

Die Wahl zwischen List & Set sollte sich darauf auswirken, wie die Abfrage an DB gesendet wird.

  • Können Sie bitte Ihre Antwort erweitern und kurz erklären, was die Auswirkungen sind?

    – Maksym Rudenko

    24. Dezember 2020 um 14:46 Uhr

  • openjpa.208410.n2.nabble.com/… Ich habe das Problem gesehen, dass OpenJPA der generierten Abfrage eine zusätzliche Order By-Klausel hinzufügt. Dies wirkt sich auf die Leistung der Datenbank für die Abfragen aus, für die keine Reihenfolge erforderlich ist. Über den obigen Link sollte dies nur geschehen, wenn die Sammlung als Liste definiert ist. Wenn es als Set definiert ist, wird diese Order By-Klausel weggelassen. Aber leider kam ich nicht von der Order By-Klausel weg, egal welchen Datentyp ich wähle.

    – Dyutiman Chaudhuri

    26. Dezember 2020 um 16:39 Uhr

Benutzer-Avatar
AmanicA

Ich denke, dass die Verwendung von Collection als generischer Standard beim Generieren von Entitäten mit Netbeans ein guter Ausgangspunkt ist. Wenn Sie dann herausfinden, was Ihr Modell tatsächlich ist und mehr Funktionalität benötigen, können Sie es einfach ändern und abwärtskompatibel bleiben.

  • Können Sie bitte Ihre Antwort erweitern und kurz erklären, was die Auswirkungen sind?

    – Maksym Rudenko

    24. Dezember 2020 um 14:46 Uhr

  • openjpa.208410.n2.nabble.com/… Ich habe das Problem gesehen, dass OpenJPA der generierten Abfrage eine zusätzliche Order By-Klausel hinzufügt. Dies wirkt sich auf die Leistung der Datenbank für die Abfragen aus, für die keine Reihenfolge erforderlich ist. Über den obigen Link sollte dies nur geschehen, wenn die Sammlung als Liste definiert ist. Wenn es als Set definiert ist, wird diese Order By-Klausel weggelassen. Aber leider kam ich nicht von der Order By-Klausel weg, egal welchen Datentyp ich wähle.

    – Dyutiman Chaudhuri

    26. Dezember 2020 um 16:39 Uhr

1178080cookie-checkWelchen Java-Typ verwenden Sie für JPA-Sammlungen und warum?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy