休眠:订购套装

2022-09-04 03:15:19

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

现在假设我有一个搜索页面,其中包含一个显示“人员”和“预订”联接的表格。我希望能够按“人”和“书”中的字段对结果进行排序,然后从Hibernate获取列表并对其进行迭代。

由于集合是一个集合,因此书籍的顺序已消失(Hibernate 的 PersistentSet 包装了未排序的书籍哈希集)。

因此,使用这种方法,我无法将结果也按“书籍”字段排序。

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

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

干杯!


答案 1

休眠支持将集合映射为 .在映射中,您基本上只需要指定一个子句。请看参考手册中的这一章SortedSetorder-by


答案 2

就像马科斯·弗拉格卡基斯说的那样

不幸的是,映射中的排序(或@OrderBy)优先,这使得标准设置的排序变得毫无用处。

但是,如果要对 Set 进行排序,则必须设置@Order。

你仍然可以使用 HQL 代替 (在休眠 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<Book> books = new HashSet<Book>(0);

        public Person() {
        }

        public Long getId() {
            return this.id;
        }

        public void setId(Long id) {
            this.id = id;
        }


      public Set<Book> getBooks() {
            return this.books;
        }

        public void setBooks(Set<Book> 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();
      }

推荐