Hibernate:@OrderBy vs @OrderColumn维护集合的顺序

时间:2012-07-11 12:58:20

标签: hibernate

在保持持久性以及从数据库检索时维护集合顺序的首选方法是什么?

我知道@OrderBy更多的是内存中的排序,只有当你按照你选择的列的顺序预先排序时才可以检索。

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

有什么想法吗?

更多详情:

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

Class A {
  List<B> bList;
}

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

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的顺序进行折腾(因为它是按Id列的顺序)。所以我的问题是,如果集合B始终保持与列表中显示的顺序相同的顺序。

1 个答案:

答案 0 :(得分:25)

OrderBy将order by子句添加到生成的SQL中,以按目标实体的表的列对检索到的集合的成员进行排序:

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

将生成类似

的SQL查询
select ... order by student.lastname ASC

OrderColumn定义表中附加列的名称,其中包含列表中实体的索引。如果更改列表中元素的顺序,Hibernate将更改此列的值。如果您的学生在此列中的值为0,3和5,则列表将为

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

在这两个注释的the javadoc中对此进行了详细描述。

编辑:

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

  • 如果您明确地致电session.save()session.saveOrUpdate(),则会为该实体分配一个ID,因此将其命名为b1,b2和b3将尊重该订单
  • AFAIK,所有其他方法(cascading,merge(),persist())不保证任何订单(除非您合并或持久,然后flush()

因此,如果您希望列表按此顺序保存b1,b2和b3,无论这些保持方式如何,最好的办法是在集合中添加@OrderColumn注释。 Hibernate将自动填充此列,其中0表示b1,1表示b2,2表示b3。当你重新加载父实体时,它们将在列表中的顺序相同。