2010-04-01 11 views
11

का ऑर्डर करना मेरे पास एक क्लास व्यक्ति है जिसमें पुस्तकें हैं। किसी विशेष आदेश में क्रमबद्ध या सॉर्ट किए गए संग्रह के लिए यह अर्थपूर्ण नहीं है।हाइबरनेट: सेट

अब कहें कि मेरे पास एक टेबल के साथ एक खोज पृष्ठ है जिसमें व्यक्ति और पुस्तक शामिल है। मैं व्यक्तियों और पुस्तक दोनों के क्षेत्रों द्वारा परिणामों को क्रमबद्ध करने में सक्षम होना चाहता हूं, और उसके बाद हाइबरनेट से एक सूची प्राप्त कर सकता हूं, और इसके ऊपर पुनरावृत्ति कर सकता हूं।

क्योंकि संग्रह एक सेट है, पुस्तकों का क्रम गायब हो गया है (हाइबरनेट के पर्सिस्टेंटसेट पुस्तकें के हैशसेट को लपेटता है, जिसे आदेश नहीं दिया जाता है)।

तो, इस दृष्टिकोण के साथ मुझे पुस्तक फ़ील्ड द्वारा भी आदेश नहीं दिए जा सकते हैं।

यदि मैं संग्रह से सूची में संग्रह बदलता हूं, तो मेरा मॉडल अर्थात् गलत है। मॉडल में आदेश रखने के लिए कोई मतलब नहीं है।

क्या किताबों के क्रम को रखने के लिए कोई दृष्टिकोण है? शायद PersistentSet को एक LinkedHashSet (जिसे आदेश दिया गया है) को लपेटने का एक तरीका है, जहां आदेश मेरी खोज मानदंड द्वारा परिभाषित किया गया है?

चीयर्स!

उत्तर

6

हाइबरनेट SortedSet के रूप में संग्रह को मैप करने का समर्थन करता है। आपके मैपिंग में आपको मूल रूप से केवल order-by खंड निर्दिष्ट करने की आवश्यकता होती है। this chapter in the reference manual पर एक नज़र डालें।

+1

प्रतिक्रिया (+1) के लिए धन्यवाद। हाँ, मैंने इसे देखा है। लेकिन उदाहरण में उन्होंने तय किया है कि आदेश एक निश्चित क्षेत्र पर है। मैं चाहता हूं कि उपयोगकर्ता को यूआई में क्लिक करने के आधार पर मानदंड एपीआई के माध्यम से सेट किया जाए। –

+1

आप मैपिंग में जो भी निर्दिष्ट करते हैं उससे अलग, मानदंड क्वेरी में परिणामों के लिए ऑर्डरिंग भी निर्दिष्ट कर सकते हैं। http://docs.jboss.org/hibernate/stable/core/reference/en/html/querycriteria.html#querycriteria-ordering –

+1

हाँ आप कर सकते हैं, लेकिन दुर्भाग्यवश मैपिंग (या @OrderBy) में ऑर्डर-द्वारा प्राथमिकता लेती है , जो मानदंड द्वारा बेकार आदेश को बेकार बनाता है। या कम से कम, यह मैपिंग के आदेश के क्रमबद्ध होने के बाद आता है। –

0

यह सुनिश्चित नहीं है कि मुझे सही प्रश्न मिल गया है, लेकिन यदि आप बस अपनी सूची का एक ordererd संस्करण चाहते हैं तो आप इसे java.util.Collections क्लास और एक तुलनाकर्ता के साथ सॉर्ट कर सकते हैं। हो सकता है कि आप इस तरह अपने pojo पर एक क्षणिक विधि बनाना चाहते हैं:

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

बस एक कक्षा लिखें जो तुलनात्मक लागू करता है।

+0

-1: यह सूचियों के लिए काम करता है, लेकिन सेट के लिए नहीं है और जब भी गेटर कॉल किया जाता है तो सूची क्रमबद्ध होती है। – Kojotak

+0

आपको प्रत्येक कॉल पर संग्रह को सॉर्ट करना होगा, यदि आप ऐसे संग्रह का उपयोग करते हैं जो प्रत्येक ऐड/निकालने पर अपना ऑर्डरिंग नहीं रखता है। –

4

तरह Markos Fragkakis कहा

दुर्भाग्य से आदेश-मानचित्रण में (या @OrderBy) पूर्वता है, जो आदेश मानदंड बेकार द्वारा निर्धारित करता है लेता है।

लेकिन अगर आप सेट ऑर्डर करना चाहते हैं तो आपको @ ऑर्डर सेट करना होगा।

तुम अब भी 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(); 
     } 
3

यह एक में स्मृति तरह से यह ठीक हो जाएगा जॉइन टेबल में डुप्लिकेट करें।

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