Java 排序多个一对多关系
我有一个搜索屏幕,下面使用JSF、JBossSeam和Hibernate。有Java 排序多个一对多关系,java,hibernate,sql-order-by,seam,Java,Hibernate,Sql Order By,Seam,我有一个搜索屏幕,下面使用JSF、JBossSeam和Hibernate。有A、B和C列,其中关系如下: A (1< --; >*) B (1< --; >*) C A(1*)B(1*)C 假设A有一个列表,B有一个列表(两种关系都是一对多) UI表支持按任何列(ASC或DESC)排序,因此我希望对查询结果进行排序。这就是我在模型中使用列表的原因 然而,我得到了一个例外,Hibernate不能急切地获取多个包(它认为两个列表都是包)。有一篇有趣的博文,他们指出了以下解
A
、B
和C
列,其中关系如下:
A (1< --; >*) B (1< --; >*) C
A(1<--;>*)B(1<--;>*)C
假设A
有一个列表
,B
有一个列表
(两种关系都是一对多)
UI表支持按任何列(ASC或DESC)排序,因此我希望对查询结果进行排序。这就是我在模型中使用列表的原因
然而,我得到了一个例外,Hibernate不能急切地获取多个包(它认为两个列表都是包)。有一篇有趣的博文,他们指出了以下解决方案:
- 首先,如果不使用@OrderBy,Hibernate返回的
将包装一个PersistentSet
,它没有顺序。因此,当我在UI中迭代它时,顺序是随机的,无论数据库的顺序如何HashSet
- 其次,如果我确实使用@OrderBy,
包装了一个PersistentSet
,它有顺序,这正是我想要的但是,LinkedHashSet
属性是硬编码的,优先于我使用Collections()或HQL()设置的任何顺序。因此,我通过UI请求的所有其他订购都在它之后OrderBy
集合
,并使用了排序集
(及其实现,树集
),但我遇到了一些问题:
TreeSet
所做的(通过比较器,或通过元素的可比较接口)SortOrder.UNSORTED
,您还可以设置一个比较器。我仍然没有设法编译它,但我仍然不相信它是我所需要的创建了一个简单的Maven项目,并将其作为一个项目提交。这是我个人解决这个问题的方法。当同一个结果集可以按任何列重新排序时,在数据库中排序有什么意义?如果每次在UI上单击不同的列时都需要点击DB,那么您只需要为自己创建一个性能问题。当在内存中对集合进行排序是有意义的时候,就是这种情况 关于行李和清单,Hibernate bok说: 行李可能无法分拣(遗憾的是,没有
树状图),也可能无法列出行李清单;这个
列表元素的顺序由列表索引定义
根据Hibernate所说的和您自己的答案提供的解决方法,您可以在运行时对集合进行排序以避免出现异常
@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;
}
}
@实体
公营Aa级{
私有列表bbList-新建ArrayList();
@独身癖
公共列表getBbList(){
返回bbList;
}
@短暂的
公共列表getBbListSortedBySomeProperty(){
Collections.sort(bbList,newcomparator(){
公共整数比较(Bb o1,Bb o2){
返回o1.getSomeProperty().compareTo(o2.getSomeProperty());
}
});
返回bbList;
}
}
请注意,某些属性必须实现可比性
@实体
公共类Bb{
私有列表ccList-新建ArrayList();
@独身癖
公共列表getCcList(){
返回CCL列表;
}
}
嗨,彼得,谢谢你的回答。我的印象是,在DB中排序(和过滤)的速度要快得多,您也可以在DB中创建自己的索引。当然,我可能弄错了。如果我想要非常专门的排序,我会使用服务器排序(与Java一起),这只需要使用一个比较器就很容易了。@Péter Török(+1)表示Hibernate在运行什么said@Markos在数据库中单独排序可能会更快(特别是对于庞大的结果集),但命中数据库(几乎总是)会导致很大的延迟(数据库与客户端在同一台计算机上运行时除外)。通常情况下,延迟造成的损失比快速排序带来的损失更大。当然,请不要相信我,最好是自己在自己的设置中进行测量。@Markos这还取决于结果集的大小。如果表中有100行,则可以一次加载所有行,并且我确信在内存中对它们进行重新排序比在h中更快如果你有一百万行,你必须求助于分页,因此你甚至不能同时在内存中拥有所有的行-这可能是在数据库中进行排序的一种情况。感谢你的洞察力(+1)。不过,在我有时间进一步调查之前,我会继续在数据库中进行排序。嗨,亚瑟,谢谢你的回答。不过,我希望在数据库中进行排序。
@Entity
public class Bb {
private List<Cc> ccList - new ArrayList<Cc>();
@OneToMany
public List<Cc> getCcList() {
return ccList;
}
}