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

发布于 2024-10-03 21:13:43 字数 390 浏览 0 评论 0原文

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

背景:

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

现在,当我再次从数据库获取“logError”对象时,它仍然会被排序吗?如果是这样,我很好奇 Hibernate 是如何做到这一点的。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一杆小烟枪 2024-10-10 21:13:44

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

@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< /code> bSet 的类型为 PersistentSet,它是另一个 Set 的包装器,(在我的例子中)这是一个普通的 >哈希集。 (HashSet 不保留其元素的顺序。)

即使 Hibernate 使用 ListLinkedHashSet,仍然不建议将实现基于自然(不保证)数据库顺序。对于 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 服务器端进行排序。在我(Łukasz Rzeszotarski)看来,这两个注释都有一个弱点,即默认设置排序。我(Łukasz Rzeszotarski)宁愿 hibernate 在“看到”使用了 order by 子句时使用自己的 LinkedHashSet 实现。

@see: Hibernate sql 排序

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

扶醉桌前 2024-10-10 21:13:44

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

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.

方觉久 2024-10-10 21:13:44

当我需要保留项目列表的顺序时,我使用 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 的 Integer 属性,因此顺序会以这种方式保留。我想在 C# 中这看起来非常相似。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文