Hibernate:@OrderBy vs @OrderColumn维护集合的顺序 [英] Hibernate: @OrderBy vs @OrderColumn to maintain the order of a collection

查看:1941
本文介绍了Hibernate:@OrderBy vs @OrderColumn维护集合的顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在保持集合的顺序并同时从数据库中检索的过程中,维护集合的顺序的首选方式是什么? 我知道@OrderBy更像是一种内存排序,只有当您按照您选择的列的顺序排列行时,才可以在检索时使用。



假设我选择使用由数据库序列支持的列,将休眠确保集合中的元素以与集合中相同的顺序(例如List)持久化。



有什么想法?



更多细节:



假设我有一个类A,它与类B有一对多的关系.B有一个主键字段' Id',它由DB中的序列支持。

  A类{
列表< B> bList;
}

我一直想保留元素B在A中的顺序,如下所示: / p>

  bList = {b1,b2,b3} 

一种实现方法是使用@OrderBy(Id ASC)。这只有当列表B按照以下顺序持续时才有效:

  ---------- ------ 
Id ---- bValue
----------------

1 ----- - b1
2 ------ b2
3 ------- b3
------------------

当我们通过Id命令检索时,订单得到维护。



让集合B以如下方式持续:

  ----- ----------- 
Id ---- bValue
----------------
1 ---- - b2
2 ------ b1
3 ------- b3
------------------

当我们检索的时候,列表B的顺序是一个折腾(因为它是按列顺序列)。所以我的问题是,如果集合B总是以与列表中出现的顺序相同的顺序持续存在。

解决方案

OrderBy增加一个order by子句给生成的SQL,以通过目标实体的表的一列对检索到的集合的成员进行排序:

  @OrderBy(lastname ASC)
public List< Student>学生们;

会生成一个SQL查询,如

  select ... order by student.lastname ASC 

OrderColumn定义表中的附加列的名称,其中包含列表中实体的索引。如果您更改列表中元素的排序,Hibernate将更改此列的值。如果你的学生在这一列中有0,3和5的值,那么这个列表将是

  [student0,null, null,student3,null,student5] 

这在 javadoc

编辑:



B标识符的分配顺序取决于您如何坚持这些B实例:


  • 如果您明确地调用 session.save() session.saveOrUpdate(),这会为实体分配一个ID,所以调用它对于b1,b2和b3将遵守命令AFAIK,所有其他方法(级联,merge(),persist())不保证任何顺序(除非合并或坚持,然后 flush()



所以如果你想列表按顺序持有b1,b2和b3,不管这些持续的方式如何,最好的方法是添加一个 @OrderColumn 注释到集合。 Hibernate会自动填充此列,b1为0,b2为1,b3为2。当你重新加载父实体时,它们将在列表中以相同的顺序。


What is the preferred way for maintaining the order of a collection while persisting and also while retrieving from database?

I know that @OrderBy is more of a in-memory sorting that might work in retrieving only when you presist the rows in the order of column you chose.

Let's say I chose to use a column backed by a database sequence, will hibernate make sure that elements in collection are persisted in the same order as in collection (say List).

Any thought?

More details:

Let’s say I have a class A which has one-to-many relationship with class B. B has a primary key field, ‘Id’, which is backed by a sequence in DB.

Class A {
  List<B> bList;
}

I always wanted to retain the order of elements B in A like below:

bList = { b1, b2, b3 }

One way to achieve is using @OrderBy ("Id ASC"). This would work only when the list B is persisted in the order as below:

----------------
Id ----bValue
----------------

1------ b1
2------ b2
3-------b3
------------------

When we retrieve since it is ordered by Id, the order is maintained.

Let’say the collection B is persisted in the following way:

----------------
Id ----bValue
----------------
1------ b2
2------ b1
3-------b3
------------------

When we retrieve, the order of list B go for a toss (since it is order by Id column). So my question, if the collection B always persist in the same order as it appears in the list or not.

解决方案

OrderBy adds an order by clause to the generated SQL to order the members of the retrieved collection by a column of the table of the target entity:

@OrderBy("lastname ASC")
public List<Student> students;

will generate a SQL query like

select ... order by student.lastname ASC

OrderColumn defines the name of an additional column in the table, containing the index of the entity in the list. If you change the ordering of the elements in the list, Hibernate will change the value of this column. And if your students have 0, 3, and 5 as values in this column, the list will be

[student0, null, null, student3, null, student5]

This is well described in the javadoc of those 2 annotations.

EDIT:

The order in which B identifiers are assigned depends on how you persist these B instances:

  • if you explicitely call session.save(), of session.saveOrUpdate(), this assigns an ID to the entity, so calling it for b1, b2 and b3 will respect the order
  • AFAIK, all the other methods (cascading, merge(), persist()) don't guarantee any order (except if you merge or persist, and then flush())

So if you want the list to hold b1, b2 and b3 in this order, regardless of the way those are persisted, your best bet is to add an @OrderColumn annotation to the collection. Hibernate will automatically populate this column with 0 for b1, 1 for b2 and 2 for b3. And when you'll reload the parent entity, They will be in the same order in the list.

这篇关于Hibernate:@OrderBy vs @OrderColumn维护集合的顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆