2010-04-12 41 views
5

Tôi có một màn hình tìm kiếm, sử dụng JSF, JBoss Seam và Hibernate bên dưới. Có cột cho A, B và C, nơi mà các mối quan hệ như sau:Hibernate: đặt nhiều mối quan hệ một-nhiều

A (1 < ->) B (1 < ->) C

A có một danh sách < B > và B có một Danh sách < C> (cả hai quan hệ là một-nhiều).

Bảng giao diện người dùng hỗ trợ sắp xếp theo bất kỳ cột nào (ASC hoặc DESC), vì vậy tôi muốn kết quả của truy vấn được sắp xếp. Đây là lý do tôi sử dụng Danh sách trong mô hình.

Tuy nhiên, tôi có ngoại lệ rằng Hibernate không thể háo hức tìm nạp nhiều túi (nó coi cả hai danh sách là túi). Có một blog thú vị gửi here, và họ xác định các giải pháp sau:

  1. Sử dụng @IndexColumn chú thích (chẳng có ai trong DB của tôi, và còn gì nữa, tôi muốn vị trí của kết quả được xác định bởi thứ tự, không phải bởi một cột index)
  2. Fetch lười biếng (vì lý do hiệu suất, tôi cần phải quyến rũ háo hức)
  3. Change List để Đặt

vì vậy, tôi đã thay đổi danh sách để Set, mà bằng cách này là chính xác hơn , mô hình khôn ngoan.

  • Trước tiên, nếu không sử dụng @OrderBy, PersistentSet được trả về bởi Hibernate bao bọc một HashSet, không có thứ tự. Vì vậy, khi tôi lặp lại nó trong giao diện người dùng, thứ tự là ngẫu nhiên, bất cứ thứ tự cơ sở dữ liệu nào đã làm.
  • Thứ hai, Nếu tôi làm sử dụng @OrderBy, PersistentSet sẽ kết thúc tốt đẹp một LinkedHashSet, đã đặt hàng và là thứ tôi muốn. Tuy nhiên, thuộc tính OrderBy được mã hóa cứng và được ưu tiên hơn bất kỳ thứ tự nào tôi đặt cả bằng cách sử dụng Bộ sưu tập (link) hoặc HQL (link). Như vậy, tất cả các yêu cầu khác mà tôi yêu cầu thông qua giao diện người dùng đến sau nó.

tôi đã cố gắng một lần nữa với Bộ, và sử dụng SortedSet (và thực hiện nó, TreeSet), nhưng tôi có một số vấn đề:

  1. Tôi muốn đặt hàng sẽ diễn ra trong DB, và không có trong bộ nhớ , đó là những gì TreeSet làm (hoặc thông qua một Comparator, hoặc thông qua giao diện Comparable của các phần tử).
  2. Thứ hai, tôi nhận thấy rằng có chú thích Hibernate @Sort, có một SortOrder.UNSORTED và bạn cũng có thể đặt một Trình so sánh. Tôi vẫn chưa quản lý để biên dịch, nhưng tôi vẫn không tin rằng đó là những gì tôi cần.

Bạn có lời khuyên nào không?

UPDATE:

Một trong những yêu cầu là cho sắp xếp để diễn ra trong DB.

UPDATE2:

Tạo một dự án Maven đơn giản và cam kết nó như là một dự án Google Code. Đây là sân chơi cá nhân của tôi cho vấn đề.

Trả lời

3

điểm đặt hàng trong DB khi tập kết quả tương tự có thể được sắp xếp lại bởi bất kỳ cột là gì? Nếu bạn cần phải nhấn DB mỗi lần khi một cột khác được nhấp vào giao diện người dùng, bạn chỉ cần tạo ra một vấn đề hiệu suất cho chính mình. Đây là trường hợp chính xác khi nó có ý nghĩa để đặt hàng bộ trong bộ nhớ.

Về túi xách và các danh sách, đây là những gì Hibernate bok đã nói:

Túi có thể không được sắp xếp (không có TreeBag, không may), và cũng không có thể liệt kê; thứ tự danh sách của được xác định theo chỉ mục danh sách.

+0

Xin chào Peter, cảm ơn câu trả lời. Tôi có ấn tượng rằng việc sắp xếp (và lọc) diễn ra nhanh hơn nhiều trong DB, nơi bạn cũng có thể tạo các chỉ mục của riêng bạn. Tôi có thể bị nhầm lẫn, tất nhiên. Tôi sẽ sử dụng máy chủ phân loại (với Java), nếu tôi muốn phân loại rất chuyên ngành mà sẽ được dễ dàng chỉ với một Comparator. –

+0

@ Péter Török (1) Đối với những gì Hibernate trong hành động nói –

+0

@Markos Phân loại theo chính nó có thể được thực hiện nhanh hơn trong DB (đặc biệt đối với bộ kết quả rất lớn), nhưng nhấn DB (hầu như luôn luôn) phải gánh chịu một độ trễ đáng kể (ngoại trừ có lẽ khi DB chạy trên cùng một máy với máy khách của bạn). Thông thường, bạn sẽ mất nhiều thời gian hơn so với mức độ bạn đạt được bằng cách đặt hàng nhanh hơn. Tất nhiên không chỉ tin tôi - tốt nhất là tự mình đo lường, trong thiết lập của riêng bạn. –

0

Dựa trên những gì Hibernate trong hành động nói và thực hiện giải pháp được cung cấp bởi câu trả lời của riêng bạn, bạn có thể sắp xếp bộ sưu tập của bạn khi chạy để avoit ngoại trừ của bạn

@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; 

    } 

} 

Hãy nhận biết someProperty phải thực hiện tương đương

...

@Entity 
public class Bb { 

    private List<Cc> ccList - new ArrayList<Cc>(); 

    @OneToMany 
    public List<Cc> getCcList() { 
     return ccList; 
    } 

} 
+0

Hi Arthur, cảm ơn câu trả lời. Tuy nhiên, tôi muốn sắp xếp diễn ra trong DB. –

Các vấn đề liên quan