【问题标题】:Does hibernate preserve the order of a LinkedHashSet and if so, how?hibernate 是否保留 LinkedHashSet 的顺序,如果是,如何?
【发布时间】:2011-05-13 17:35:19
【问题描述】:

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

背景:

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

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

【问题讨论】:

  • 您是否尝试过使用@OrderColumn 进行注释? (也许那是一个 JPA 注释)

标签: java hibernate insertion linkedhashset


【解决方案1】:

首先:我假设您在谈论两个实体之间的关系。类似的东西

@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 的类型为PersistentSet,它是另一个Set 的包装器,而这个是(在我的情况下)一个普通的HashSet。 (HashSet 不保留其元素的顺序。)

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

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

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

@见:Ordering return of Child objects in JPA query


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

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

@见:Hibernate ordering in sql

【讨论】:

  • @Łukasz Rzeszotarski:如果您再次以这种方式编辑某人的帖子,那么至少要明确这是您的声明,而不是原作者的声明!
【解决方案2】:

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

【讨论】:

  • LinkedHashSet 有插入顺序
【解决方案3】:

当我需要保持项目列表的顺序时,我使用Map 而不是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 示例中,positionRuleAction 的一个整数属性,因此顺序以这种方式保持不变。我猜在C# 这看起来会很相似。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-28
    • 2012-04-19
    • 2010-10-14
    • 2017-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多