17

hibernate 是否保留 LinkedHashSet 的顺序,如果是,如何?如果这取决于数据库的类型,我想知道 PostgreSQL 的情况。

背景:

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

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

4

3 回答 3

16

首先:我假设您正在谈论两个实体之间的关系。就像是

@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 本身不会保留顺序!

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

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

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

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

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


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

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

@see: sql 中的休眠排序

于 2010-11-22T10:26:41.690 回答
0

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

于 2010-11-22T10:18:34.127 回答
0

当我需要保持项目列表的顺序时,我使用 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 }));

在此Java示例中,position是一个整数属性,RuleAction因此顺序以这种方式保持不变。我想C#这看起来会很相似。

于 2014-12-25T19:09:28.547 回答