Does hibernate preserve the order of a LinkedHashSet and if so, how? In case this depends on the type of database, I'd like to know this for PostgreSQL.
Background:
I know what a LinkedHashSet is for, and the reason I'm asking this is because I'm logging the names of some functions I execute to a 'logError' table that has a many-to-many relation to some 'functionName' table. I need these functions to remain in the same order as when I executed them, so first I find the corresponding 'functionName' objects, put them in a LinkedHashSet (after each function that failed) and then I persist the 'logError' object.
Now when I get the 'logError' object from the database again, will it still be ordered? And if so, I was curious how this is done by Hibernate.
First: I assume you are talking about a relationship between two entities. Something like
@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 does not preserve the order by itself!
If you have a look at the classes used when entity A
is loaded from the database, then the Set
bSet
is of type PersistentSet
, which is a wrapper around another Set
, and this is (in my case) a normal HashSet
. (HashSet
does not preserve the order of its elements.)
Even if Hibernate used List
or LinkedHashSet
, it is still inadvisable to base the implementation on the natural (not guaranteed) database order. For MySQL it is some kind of anti-pattern.
But you can use the @Sort
annotation (org.hibernate.annotations.Sort
) to make your sorting explicit. For example:
@OneToMany(mappedBy = "as")
@Sort(type = SortType.COMPARATOR, comparator = MyBComparator.class);
public SortedSet<C> cs;
@see: Ordering return of Child objects in JPA query
Added by Łukasz Rzeszotarski on 1th Sep 2012:
But we have to remember that using @Sort
annotation causes sorting objects in memory (jvm) and not in sql. Instead we can use @OrderBy
annotation that causes sorting on the sql server side. Both of these annotations have in my (Łukasz Rzeszotarski ) opinion one weakness that set up ordering by default. I (Łukasz Rzeszotarski ) would rather hibernate uses own LinkedHashSet implementation when it 'sees' that order by clause is used.