我有一个搜索屏幕,下面是JSF,JBoss Seam和Hibernate。 A
,B
和C
有列,其关系如下:
A (1< --; >*) B (1< --; >*) C
假设A
有List< B >
而B
有List< C >
(两者的关系都是一对多)。
UI表支持按任何列(ASC或DESC)排序,因此我希望对查询结果进行排序。这就是我在模型中使用Lists的原因。
然而,我得到一个例外,即Hibernate无法急切地获取多个行李(它认为两个行李都是行李)。有一篇有趣的博客文章here,他们确定了以下解决方案:
我将List更改为Set,顺便提一下,模型更正确。
PersistentSet
会包含一个HashSet
,它没有排序。因此,当我在UI中迭代它时,顺序是随机的,无论数据库的顺序如何。PersistentSet
会包含一个LinkedHashSet
,它有订购,这就是我想要的。 但是,OrderBy
属性是硬编码的,并且优先于我使用集合(link)或HQL(link)设置的任何顺序。因此,我通过UI请求的所有其他订单都在它之后。我再次尝试使用Sets
,并使用SortedSet
(及其实现,TreeSet
),但我遇到了一些问题:
我想要在DB中进行排序,而不是在内存中,这是TreeSet
所做的(通过比较器,或通过元素的Comparable接口)。
我发现有一个Hibernate注释@Sort,它有SortOrder.UNSORTED
,你也可以设置一个比较器。我仍然没有设法编译,但我仍然不相信它是我需要的。
其中一个要求是在DB中进行排序。
创建一个简单的Maven项目并将其作为Google Code项目提交。这是我个人解决问题的方法。
答案 0 :(得分:3)
当任何列重新排序相同的结果集时,DB中的排序点是什么?如果每次在UI上单击不同的列时都需要访问数据库,则只需为自己创建性能问题。当在内存中对集合进行排序时,就是这种情况。
关于包包和清单,这就是Hibernate bok所说的:
行李可能没有排序(不幸的是没有
TreeBag
),也可能没有列表;该 列表元素的顺序由列表索引定义。
答案 1 :(得分:0)
根据Hibernate in Action所说的内容以及您自己的答案提供的解决方法,您可以在运行时对进行排序以避免异常
@Entity
public class Aa {
private List<Bb> bbList - new ArrayList<Bb>();
@OneToMany
public List<Bb> getBbList() {
return bbList;
}
@Transient
public List<Bb> getBbListSortedBySomeProperty() {
Collections.sort(bbList, new Comparator<Bb>() {
public int compare(Bb o1, Bb o2) {
return o1.getSomeProperty().compareTo(o2.getSomeProperty());
}
});
return bbList;
}
}
请注意someProperty必须实现Comparable
...
@Entity
public class Bb {
private List<Cc> ccList - new ArrayList<Cc>();
@OneToMany
public List<Cc> getCcList() {
return ccList;
}
}