java hibernate 是否保留 LinkedHashSet 的顺序,如果是,如何保留?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4243865/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 05:28:44  来源:igfitidea点击:

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

javahibernateinsertionlinkedhashset

提问by FinalArt2005

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.

hibernate 是否保留 LinkedHashSet 的顺序,如果是,如何保留?如果这取决于数据库的类型,我想知道 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.

我知道 LinkedHashSet 是做什么用的,我问这个的原因是因为我正在将我执行的某些函数的名称记录到与某些“functionName”表具有多对多关系的“logError”表中. 我需要这些函数保持与执行它们时相同的顺序,所以首先我找到相应的“functionName”对象,将它们放入 LinkedHashSet(在每个失败的函数之后),然后我保留“logError”对象。

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.

现在,当我再次从数据库中获取 'logError' 对象时,它还会被订购吗?如果是这样,我很好奇 Hibernate 是如何做到这一点的。

采纳答案by Ralph

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!

Hibernate 不会自行保存顺序!

If you have a look at the classes used when entity Ais loaded from the database, then the SetbSetis of type PersistentSet, which is a wrapper around another Set, and this is (in my case) a normal HashSet. (HashSetdoes not preserve the order of its elements.)

如果您查看A从数据库加载实体时使用的类,那么SetbSetis 是 type PersistentSet,它是另一个 的包装器Set,这是(在我的情况下)一个普通的HashSet. (HashSet不保留其元素的顺序。)

Even if Hibernate used Listor 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.

即使 Hibernate 使用了Listor LinkedHashSet,仍然不建议基于自然(不保证)的数据库顺序来实现。对于 MySQL,它是某种反模式。

But you can use the @Sortannotation (org.hibernate.annotations.Sort) to make your sorting explicit. For example:

但是您可以使用@Sort注释 ( org.hibernate.annotations.Sort) 来明确您的排序。例如:

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

@see: Ordering return of Child objects in JPA query

@see:在 JPA 查询中排序返回子对象



Added by ?ukasz Rzeszotarski on 1th Sep 2012:

?ukasz Rzeszotarski 于 2012 年 9 月 1 日添加:

But we have to remember that using @Sortannotation causes sorting objects in memory (jvm) and not in sql. Instead we can use @OrderByannotation 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.

但是我们必须记住,使用@Sort注解会导致在内存(jvm)中而不是在 sql 中对对象进行排序。相反,我们可以使用@OrderBy在 sql server 端导致排序的注释。我 (?ukasz Rzeszotarski ) 认为这两个注释都有一个弱点,即默认设置排序。我 (?ukasz Rzeszotarski ) 宁愿休眠使用自己的 LinkedHashSet 实现,当它“看到”使用 order by 子句时。

@see: Hibernate ordering in sql

@see:sql 中的休眠排序

回答by yglodt

When I need to persist the order of a List of items, I use a Mapand not a List.

当我需要保持项目列表的顺序时,我使用 aMap而不是 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 Javaexample, positionis an Integer property of RuleActionso the order is persisted that way. I guess in C#this would look rather similar.

在这个Java例子中,position是一个 Integer 属性,RuleAction所以订单以这种方式持久化。我想C#这看起来很相似。

回答by PaulJWilliams

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.

集合没有固有的“顺序”,数据库表也没有 - 您可以在查询数据时应用顺序,但除非您保留该顺序(例如,通过逐行获取行并将它们放入有序容器中,如链接list) 那么返回的数据也将是无序的。