我有一个搜索屏幕,在下面使用 JSF、JBoss Seam 和 Hibernate。有 A
的列, B
, 和 C
,其中关系如下:
A (1< --; >*) B (1< --; >*) C
假设A
有一个 List< B >
和 B
有一个 List< C >
(两种关系都是一对多的)。
UI 表支持按任何列(ASC 或 DESC)排序,因此我希望查询的结果能够排序。这就是我在模型中使用列表的原因。
但是,我遇到一个异常,即 Hibernate 无法急切地获取多个包(它认为两个列表都是包)。有一篇有趣的博文 here , 他们确定了以下解决方案:
- 使用@IndexColumn`注解(我的数据库中没有,而且我希望结果的位置由顺序决定,而不是由索引列决定)
- 延迟获取(出于性能原因,我需要急切获取)
- 更改要设置的列表
我将 List 更改为 Set,顺便说一下,这在模型方面更正确。
- 首先,如果不使用@OrderBy,
PersistentSet
Hibernate 返回的包装了一个HashSet
, 没有顺序。因此,当我在 UI 中对其进行迭代时,顺序是随机的,无论数据库的顺序如何。 - 其次,如果我确实使用@OrderBy,
PersistentSet
包装LinkedHashSet
,它有顺序,是我想要的。 但是,OrderBy
属性是硬编码的,并且优先于我使用集合(link)或 HQL(link)设置的任何顺序。因此,我通过 UI 请求的所有其他排序都在它之后。
我再次尝试 Sets
, 并使用 SortedSet
(及其实现,TreeSet
),但我有一些问题:
我希望在数据库中而不是在内存中进行排序,这就是
TreeSet
做(通过 Comparator 或通过元素的 Comparable 接口(interface))。我发现有Hibernate注解@Sort,它有一个
SortOrder.UNSORTED
你也可以设置一个比较器。我仍然没有成功编译它,但我仍然不相信它是我需要的。
要求之一是在数据库中进行排序。
创建了一个简单的 Maven 项目并将其提交为 Google Code项目。这是我解决这个问题的个人 Playground 。
最佳答案
当相同的结果集可以按任何列重新排序时,在数据库中排序有什么意义?如果每次在 UI 上单击不同的列时都需要访问数据库,那么只会给自己造成性能问题。当在内存中对集合进行排序是有意义的时,情况就是如此。
关于bags和lists,Hibernate bok是这么说的:
Bags may not be sorted (there is no
TreeBag
, unfortunately), nor may lists; the order of list elements is defined by the list index.
关于java - 订购多个一对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2622233/