hibernate:如何映射 Set 关联以便保留 HQL order by

发布于 2024-12-04 12:12:40 字数 877 浏览 4 评论 0原文

好的,这看起来很像 Hibernate 中的(另一个)错误/未实现的功能。

是否可以以尊重 HQL 中的 "order by" 子句的方式映射 Set 关联?

例如,假设您有 2 个实体:PageEntityQuestionEntity。一个页面有一个集合。

如何使以下 HQL 工作:

from
    PageEntity p
        left outer join fetch p.questionEntities q
order by
    q.orderIndex

我不想要的:

  • 在 Java 中使用排序(我们在 SQL 中有“order by”,所以我们不必这样做!)。 SortedSet、Comparator 等不可能将
  • 其映射为带有 的 List。这会将“order by”添加到所有 SQL 查询中,并且我不希望它
  • 使用 因为这将再次应用于 在所有查询

调试中,我看到正在使用的 Set 的实现是 org.hibernate.collection.PersistentSet ,它包装了一个 Set 。包装的Set 的实现是HashSet。我希望 Hibernate 能够足够聪明地使用 LinkedHashSet 来代替,这样它就可以遵守我的“order by”HQL 子句。

OK, this looks mostly like (another) bug/unimplemented functionality in Hibernate.

Is it possible to map a Set association in such a way that the "order by" clause in HQL is respected?

For example, say you have 2 entities: PageEntity and QuestionEntity. A page has a Set.

How do I make the following HQL work:

from
    PageEntity p
        left outer join fetch p.questionEntities q
order by
    q.orderIndex

What I don't want:

  • to use sort in Java (we have "order by" in SQL so we don't have to do this!). SortedSet, Comparators etc. are out of the question
  • to map it as a List with a <list-index>. This will add the "order by" to all SQL queries, and I don't want this
  • to use a <set order-by="orderIndex"> because again, this will be applied to all queries

Debugging, I see that the implementation of Set that is being used is org.hibernate.collection.PersistentSet which wraps a Set. The implementation of the wrapped Set is HashSet. I would expect Hibernate to be smart enough to use a LinkedHashSet instead, so that it can honor my "order by" HQL clause.

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

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

发布评论

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

评论(3

病毒体 2024-12-11 12:12:40

我很确定 Hibernate 无法为您执行此操作,并且建议使用 List 代替。要删除连接引入的重复项,您可以使用 独特关键字。生成的List将与任何Set一样好。

如果您仍然需要在有序 Set 中使用它们(可能涉及第 3 方 API),您可以创建自己的 LinkedHashSet 并将所有对象移动到那里:

List<PageEntity> list = runQuery(...);
return new LinkedHashSet<PageEntity>(list);

I'm pretty sure Hibernate can't do this for you, and would recommend using a List instead. To remove duplicates introduced by the join, you can use the distinct keyword. The resulting List will be just as good as any Set.

If you still need them in an ordered Set (maybe there's a 3rd party API involved) you could create your own LinkedHashSet and move all objects there:

List<PageEntity> list = runQuery(...);
return new LinkedHashSet<PageEntity>(list);
归途 2024-12-11 12:12:40

您似乎希望获得按 q.orderIndex 排序的结果,但

  • 您希望对 PageEntity 的结果列表进行排序吗?
  • 或者(正如我所想)您是否希望对每个 PageEntity 的 QuestionEntity 集进行排序?

如果您想要后者:Java 中的Set不会保留顺序。

编辑后: no Hibernate 不必智能:如果您将集合定义为Set,它将被视为一个集合。在许多应用中,保留订单会耗费资源,但并不是必需的。

It seems you want to get results sorted by q.orderIndex but

  • do you want the resulting list of PageEntity to be sorted?
  • or (as I think) do you want the set of QuestionEntitys for each PageEntity to be sorted?

If you want the latter: Sets in Java do not preserve order.

After your edit: no Hibernate does not have to be smart: if you define your collection to be a Set it will be treated as a set. There are many applications where preserving the order costs resources and is not needed.

救赎№ 2024-12-11 12:12:40

order by 适用于查询结果。不适用于问题集中的实体。我不认为这是一个错误:如果返回的页面实体之一已加载到会话中,并使用另一个带有另一个 order by 子句的查询,它会做什么?

如果您想要一个有序的问题列表,请选择问题:

select q from QuestionEntity q inner join fetch q.page p order by q.orderIndex

select p, q from PageEntity p
left outer join fetch p.questionEntities q 
order by q.orderIndex

应该可以解决问题。

order by applies to the results of the query. Not to the entities in the collection of questions. I don't think it's a bug: what would it do if one of the returned page entity is already loaded in the session, using another query with another order by clause?

If you want an ordered list of questions, select the questions:

select q from QuestionEntity q inner join fetch q.page p order by q.orderIndex

or

select p, q from PageEntity p
left outer join fetch p.questionEntities q 
order by q.orderIndex

should do the trick.

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