2010-11-22 2 views
13

Speichert Hibernate die Reihenfolge eines LinkedHashSet und wenn ja, wie? Falls dies von der Art der Datenbank abhängt, würde ich das gerne für PostgreSQL wissen.Überwintert der Winterschlaf die Reihenfolge eines LinkedHashSets und wenn ja, wie?

Hintergrund:

Ich weiß, was ein LinkedHashSet für ist, und der Grund, warum ich dies zu fragen, weil ich die Namen einiger Funktionen bin ich die Anmeldung zu einer ‚logError‘ Tabelle ausführen, die eine hat Viele-zu-Viele-Beziehung zu einer 'FunktionsName'-Tabelle. Ich brauche diese Funktionen, um in der gleichen Reihenfolge zu bleiben, wie wenn ich sie ausgeführt habe, also finde ich zuerst die entsprechenden 'functionName'-Objekte, setze sie in ein LinkedHashSet (nach jeder fehlgeschlagenen Funktion) und behalte dann das' logError'-Objekt.

Jetzt, wenn ich das "logError" -Objekt wieder aus der Datenbank bekomme, wird es noch bestellt? Und wenn ja, war ich neugierig, wie Hibernate das macht.

+1

Haben Sie versucht, mit @OrderColumn zu kommentieren? (vielleicht ist das eine JPA-Annotation) – willcodejavaforfood

Antwort

13

Erstens: Ich nehme an, Sie sprechen über eine Beziehung zwischen zwei Entitäten. So etwas wie

@Entity 
public class A { 
@ManyToMany 
    @JoinTable(name = "A_B", joinColumns = { @JoinColumn(name = "A_fk") }, inverseJoinColumns = { @JoinColumn(name = "B_fk") }) 
    private Set<B> bSet = new LinkedHashSet<B>(); 
} 

Hibernate erhalten die Bestellung nicht von selbst!

Wenn Sie einen Blick auf die Klassen verwendet haben, wenn Unternehmen A aus der Datenbank geladen wird, dann ist die SetbSet vom Typ PersistentSet, die ein Wrapper um ein anderes Set ist, und dies ist (in meinem Fall) ein normaler HashSet. (HashSet nicht die Reihenfolge der Elemente bewahren.)

Auch wenn Hibernate verwendete List oder LinkedHashSet, ist es noch nicht ratsam ist, die Umsetzung auf der natürlichen (nicht garantiert) Datenbank, um zu stützen. Für MySQL ist es eine Art Anti-Pattern.

Sie können jedoch die @Sort Annotation (org.hibernate.annotations.Sort) verwenden, um Ihre Sortierung explizit zu machen. Zum Beispiel:

@OneToMany(mappedBy = "as") 
@Sort(type = SortType.COMPARATOR, comparator = MyBComparator.class); 
public SortedSet<C> cs; 

@see: Ordering return of Child objects in JPA query


Hinzugefügt von Łukasz Rzeszotarski am 1. September 2012:

Aber wir müssen bedenken, dass die Verwendung von @Sort Anmerkung verursacht in Sortieren von Objekten Speicher (jvm) und nicht in SQL. Stattdessen können wir @OrderBy Annotation verwenden, die Sortierung auf der SQL Server-Seite verursacht. Beide Anmerkungen haben in meiner (Łukasz Rzeszotarski) Meinung eine Schwäche, die standardmäßig die Bestellung aufstellt. Ich (Łukasz Rzeszotarski) würde lieber den Winterschlaf mit der eigenen LinkedHashSet-Implementierung machen, wenn er sieht, dass die order by-Klausel verwendet wird.

@see: Hibernate ordering in sql

+3

@ Łukasz Rzeszotarski: Wenn Sie jemandes Post auf diese Weise wieder bearbeiten, dann machen Sie zumindest klar, dass dies Ihre Aussage war, und nicht die ursprünglichen Autoren! – Ralph

+0

Dies ist eine dumme Antwort, wenn Sie wirklich normale Karte und nicht Entity Relation haben und Sie wollen nur die Reihenfolge über 'LinkedHashMap' beibehalten – Enerccio

+0

@Enerccio: die Frage ist, wie Ruhezustand (oder nicht) die Reihenfolge eines LinkedHashSet, ist es nicht über Sie wollen, dass sie eine Karte speichern. Wenn du denkst, dass meine Antwort falsch ist (vielleicht ist es das), dann schreibe bitte eine bessere richtige Antwort und ich werde meine eine verbessern und deine verbessern. – Ralph

0

Mengen haben keine inhärente "Reihenfolge", auch keine Datenbanktabellen - Sie können eine Bestellung anwenden, wenn Sie die Daten abfragen, aber Sie behalten diese Reihenfolge bei (z. B. indem Sie Reihen nacheinander sortieren und ordnen Container wie eine verknüpfte Liste), dann werden die zurückgegebenen Daten ebenfalls nicht geordnet.

+1

LinkedHashSet hat einen Anzeigenauftrag – willcodejavaforfood

0

Wenn ich brauche die Reihenfolge einer Liste der Elemente zu bestehen, verwende ich ein Map und keine List.

@OneToMany(fetch = FetchType.EAGER, mappedBy = "rule", cascade = CascadeType.ALL) 
@MapKey(name = "position") 
private Map<Integer, RuleAction> actions    = LazyMap.decorate(new LinkedHashMap<>(), FactoryUtils.instantiateFactory(RuleAction.class, new Class[] { Rule.class }, new Object[] { this })); 

In diesem Java Beispiel position ist eine Integer-Eigenschaft RuleAction so der Auftrag auf diese Weise beibehalten wird. Ich denke in C# würde das ziemlich ähnlich aussehen.

Verwandte Themen