Does hibernate preserve the order of a LinkedHashSet and if so, how?

余生长醉 提交于 2019-12-21 07:14:05

问题


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.


回答1:


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.

@see: Hibernate ordering in sql




回答2:


Sets do not have an inherent 'order', nor do database tables - you can apply an order when you query the data, but unless you preserve that order (eg by getting rows one by one and putting them into an ordered container like a linked list) then the returned data will be unordered too.




回答3:


When I need to persist the order of a List of items, I use a Map and not a 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 this Java example, position is an Integer property of RuleAction so the order is persisted that way. I guess in C# this would look rather similar.



来源:https://stackoverflow.com/questions/4243865/does-hibernate-preserve-the-order-of-a-linkedhashset-and-if-so-how

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!