Hibernate:订购一套

我有一个有一套书的人。 在特定情况下,拥有有序或有序集合是没有意义的。

现在说我有一个搜索页面,其中有一个表格显示了Person和Book的连接。 我希望能够通过Person和Book中的字段对结果进行排序,然后从Hibernate获取List,并迭代它。

因为集合是一个集合,所以书籍的排序已经消失(Hibernate的PersistentSet包装了一个HashSet of Books,它没有被订购)。

因此,通过这种方法,我无法通过Book字段排序结果。

如果我将集合从Set更改为List,我的模型在语义上是不正确的。 保持模型中的顺序没有意义。

有没有办法保持书籍的顺序? 也许PersistentSet有一种方法可以包装一个LinkedHashSet(有序),其中的顺序由我的搜索条件定义?

干杯!

Hibernate支持将集合映射为SortedSet 。 在你的映射中,你基本上只需要指定一个order-by子句。 请参阅参考手册中的这一章 。

就像Markos Fragkakis说的那样

遗憾的是,映射(或@OrderBy)中的order-by优先,这使得Criteria设置的排序无用。

但是如果你想让Set有序,你必须设置@Order。

您仍然可以使用HQL(在hibernate 3.3.2.GA上测试),它首先按hql查询中的顺序排序:

  @Entity @Table(name = "Person") public class Person { @Id @Column(name = "ID_PERSON", unique = true, nullable = false, precision = 8, scale = 0) private Long id; @OneToMany(fetch = FetchType.LAZY, mappedBy = "person") @OrderBy private Set books = new HashSet(0); public Person() { } public Long getId() { return this.id; } public void setId(Long id) { this.id = id; } public Set getBooks() { return this.books; } public void setBooks(Set books) { this.books = books; } } /** * hql Version * * Result in : * order by * book1_.TITLE asc, * book1_.ID_BOOK asc **/ @Override public Person getFullPerson(Long idPerson) { StringBuilder hqlQuery = new StringBuilder(); hqlQuery.append("from Person as p "); hqlQuery.append("left join fetch p.books as book "); hqlQuery.append("where p.id = :idPerson "); hqlQuery.append("order by book.title "); Query query = createQuery(hqlQuery.toString()); query.setLong("idPerson", id); return uniqueResult(query); } /** * criteria Version // not usable * * Result in : * order by * book1_.ID_BOOK asc, * book1_.TITLE asc **/ @Override public Person getFullPersonCriteria(Long idPerson) { Criteria criteria = ... criteria.add(Restrictions.eq("id", idPerson)); criteria.createAlias("books", "book", CriteriaSpecification.LEFT_JOIN); criteria.addOrder(Order.asc("book.title")); return criteria.uniqueResult(); } 

这是一种内存中的排序,它将处理连接表中的重复项。

  @OneToMany @JoinTable(name = "person_book", joinColumns = @JoinColumn(name = "person_id"), inverseJoinColumns = @JoinColumn(name = "book_id")) @Sort(type = SortType.COMPARATOR, comparator = MyBookComparator.class) private SortedSet books; 

不确定我是否正确的问题,但如果您只想要列表的ordererd版本,您可以使用java.util.Collections类和Comparator对其进行排序。 也许你想在你的pojo上制作一个瞬态方法,如下所示:

 @Transient public List getBooksASC() { Collections.sort(this.books, new BookSorter.TitelASCSorter()); return this.books; } 

只需编写一个实现Comparator的Class。