JPA/Hibernate: Reihenfolge der Elemente einer Liste stabil bei/nach Persistierung?

DarthShader

Erfahrenes Mitglied
Hallo zusammen,

kann man, sagen wir aus Sicht der JPA Spezifikation, oder aus Sicht der Hibernate Dokumentation (oder irgendeiner anderen Referenz/Quelle), davon ausgehen, dass die Reihenfolge der Elemente in einer Liste (z.B. ein Member einer Klasse vom Typ "List" oder "Set") stets erhalten bleibt, wenn man diese persistiert und danach wieder aus der Datenbank lädt?

Ich meine natürlich, ohne im Query irgendeine Order o.Ä. anzugeben oder das Mapping sonstwie zu beeinflussen - also eine reine "OneToMany" bzw. "ManyToOne" Beziehung. Entspricht die Reihenfolge der Elemente in der Java Liste dann immer der Reihenfolge der Elemente in der Tabelle?

Ich habe die Erfahrung gemacht, dass dies so ist. Aber bevor ich mich darauf sicher verlasse, hätte ich gerne eine verlässliche Quelle, die mir das bestätigt.


Vielen Dank für Eure Hilfe!
 
Hallo,

Ich habe die Erfahrung gemacht, dass dies so ist. Aber bevor ich mich darauf sicher verlasse, hätte ich gerne eine verlässliche Quelle, die mir das bestätigt.
Das habe ich auch schon beobachtet, hab das aber noch nicht explizit wo stehen sehen...
wenn man per Hibernate eine List<SomeEntity> nachlädt kommen die Elemente in der Reihenfolge wie sie zuvor persistert wurden bzw. wie sie in ihrer "natürlichen" Ordnung vorliegen. Im Gegensatz dazu kann die Reihenfolge beim nachladen eines Set<SomeEntity> variieren. Das sieht man AFAIK auch sehr schon, das für List<...> eine andere SQL Query generiert wird als für ein Set<....>. Natürlich gibts zusätzlich noch den Unterschied, dass man bei einer List doppelte Einträge haben kann und bei einem Set nicht.

Gruß Tom
 
Hallo Thomas,

vielen Dank für Deine Antwort - ich habe nochmal verschiedene Docs durchgesehen, konnte aber keine Bestätigung finden. Da die Reihenfolge der Elemente in meinem speziellen Anwendungsfall hier gerade eine sicherheitskritische Rolle spielen, werde ich mich nicht einfach auf meine Beobachtung verlassen, sondern eine extra Spalte für die Reihenfolge hinzufügen.

Nochmals danke!
 
Hallo DarthShader,

Weder Set noch List sind in Deinem Sinne stabil. Du kannst Dich nicht auf Deine Beobachtung verlassen.

Eine stabile Reihenfolge bekommst Du nur mit irgendeiner ausdrücklichen Ordnung.

- Im Arbeitsspeicher mittels eines Comparators sortieren: @Sort
- Indexspalte einführen: @OrderColumn
- Order By in der Query

Gruß
Alexander
 
Hallo Alexander,

vielen Dank für Deine Antwort.

Kann man denn irgendwo nachlesen, dass man sich nicht auf die Reihenfolge verlassen kann? Natürlich sollte man sich im Umkehrschluss nicht darauf verlassen, wenn es auch nirgends steht ;)

Ich hab jedenfalls noch nie erlebt, dass die Reihenfolge nach dem Laden aus der Datenbank nicht mehr stimmte bzw. dieselbe war, wir beim Persistieren. Kennst Du einen Anwendungsfall, wo man deutlich sieht, dass es schief gehen kann, wenn man sich einfach auf die Reihenfolge verlässt?

Danke für die Hinweise bezüglich der alternativen Möglichkeiten (@Sort, @OrderColumn etc.).
 
Hallo DarthShader,

Ich kenne es so, dass in der Regel die Datensätze bei Abfragen ohne Sortierkriterium in der Reihe geliefert werden, wie sie zuvor eingefügt wurden.

Ein Fehlverhalten kannst Du wie folgt provozieren:
- Vaterobjekt mit 2 Kindobjekten speichern.
- Vaterobjekt wieder laden.
--> Reihenfolge ist so wie Du sie vermutlich erwartest.
- 0tes Kindobjekt aus der Liste entfernen und löschen.
- An der 0ten Stelle wieder ein neues Kindobjekt in die Liste einfügen und speichern.
--> Jetzt ist neues Objekt vor dem Alten.
- Vaterobjekt wieder laden.
--> Schwups, jetzt ist neues Objekt nach dem Alten.

Gruß
Alexander
 
Hallo Alexander,

so wird natürlich klar, dass es nicht immer stimmen kann. In einem solchen Fall bildet sich quasi der Index des Elements einer Liste auf die id in der Tabelle ab. Den Eintrag an einem bestimmten Index, z.B. in einer ArrayList, kann man natürlich ersetzen, aber bei z.B. einer Autoincrement-Spalte in der DB kann man die ids nicht "wiederverwenden", diese werden ja stetig inkrementiert.

Vielen Dank für das Beispiel!
 
Zurück