2010-04-01 30 views
11

Tôi có một Người có một nhóm Sách. Nó không có ý nghĩa trong trường hợp cụ thể để có một bộ sưu tập được sắp xếp hoặc sắp xếp.Hibernate: đặt hàng một Bộ

Giả sử bây giờ tôi có một trang tìm kiếm với một bảng hiển thị sự tham gia của Person and Book. Tôi muốn để có thể sắp xếp các kết quả theo các lĩnh vực từ cả hai người và cuốn sách, và sau đó nhận được một danh sách từ Hibernate, và lặp qua nó.

Vì bộ sưu tập là Tập hợp, thứ tự của Sách đã biến mất (PersistentSet of Hibernate kết thúc tốt đẹp một HashSet of Books, không được đặt hàng).

Vì vậy, với cách tiếp cận này, tôi không thể có kết quả cũng được sắp xếp theo các trường Sách.

Nếu tôi thay đổi bộ sưu tập từ Đặt thành Danh sách, mô hình của tôi không chính xác về mặt ngữ nghĩa. Không có ý nghĩa gì trong việc giữ trật tự trong mô hình.

Có cách tiếp cận nào để giữ trật tự Sách không? Có lẽ có một cách để PersistentSet bọc một LinkedHashSet (được sắp xếp), trong đó thứ tự được xác định bởi tiêu chí tìm kiếm của tôi?

Chúc mừng!

Trả lời

6

Hibernate hỗ trợ ánh xạ một bộ sưu tập dưới dạng SortedSet. Trong ánh xạ của bạn, về cơ bản bạn chỉ cần xác định mệnh đề order-by. Hãy xem this chapter in the reference manual.

+1

Cảm ơn phản hồi (+1). Vâng, tôi đã thấy điều đó. Nhưng trong ví dụ họ đã cố định rằng thứ tự nằm trên một trường nhất định. Tôi muốn (các) trường đó được đặt thông qua API tiêu chí, tùy thuộc vào những gì người dùng đã nhấp vào trong giao diện người dùng. –

+1

Bạn cũng có thể chỉ định thứ tự cho kết quả trong truy vấn Tiêu chí, tách biệt với bất kỳ điều gì bạn chỉ định trong ánh xạ. http://docs.jboss.org/hibernate/stable/core/reference/en/html/querycriteria.html#querycriteria-ordering –

+1

Có thể, nhưng thứ tự không may trong bản đồ (hoặc @OrderBy) được ưu tiên , khiến cho việc đặt hàng được đặt ra bởi Tiêu chí vô dụng. Hoặc ít nhất, nó xuất hiện sau khi sắp xếp thứ tự của bản đồ. –

0

không chắc chắn nếu tôi có câu hỏi đúng nhưng nếu bạn chỉ muốn một phiên bản ordererd của danh sách của bạn, bạn chỉ có thể sắp xếp nó với lớp java.util.Collections và một Comparator. Có thể bạn muốn tạo một Phương thức tạm thời trên pojo của bạn như thế này:

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

Chỉ cần viết một lớp thực hiện Bộ so sánh.

+0

-1: Điều này làm việc cho các danh sách, nhưng không phải cho các bộ và danh sách được sắp xếp mỗi lần getter được gọi. – Kojotak

+0

bạn phải sắp xếp bộ sưu tập trên mọi cuộc gọi, nếu bạn sử dụng bộ sưu tập không giữ lại thứ tự của nó trên mỗi lần thêm/xóa. –

4

Giống như nói Markos Fragkakis

không may trật tự-do trong việc lập bản đồ (hoặc @OrderBy) được ưu tiên, mà làm cho trật tự theo quy định của Tiêu chuẩn vô dụng.

Nhưng bạn phải đặt @Order nếu bạn muốn đặt Đơn đặt hàng.

Bạn vẫn có thể sử dụng HQL thay vì (thử nghiệm trên Hibernate 3.3.2.GA), người đặt hàng đầu tiên theo lệnh trong truy vấn 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(); 
     } 
3

Đây là một trong bộ nhớ loại mà sẽ chăm sóc các bản sao trong bảng kết nối.

@OneToMany 
    @JoinTable(name = "person_book", joinColumns = @JoinColumn(name = "person_id"), 
      inverseJoinColumns = @JoinColumn(name = "book_id")) 
    @Sort(type = SortType.COMPARATOR, comparator = MyBookComparator.class) 
    private SortedSet<BookEntity> books; 
Các vấn đề liên quan