2011-07-19 7 views
10

@ElementCollection का उपयोग करते समय लोड करें ऑब्जेक्ट के कई उदाहरण लोड हो रहा है। अधिक विशेष रूप से, यह संग्रह OfStrings में प्रत्येक तत्व के लिए एक उदाहरण लोड कर रहा है।@ElementCollection Java Persistence (हाइबरनेट) कारण डुप्लिकेट इंस्टेंस की लोडिंग

उदाहरण के लिए, संग्रह के साथ MyClass के एक उदाहरण के साथ एक डेटाबेस डेटाबेस OfStrings.size() == 4, सभी MyClass मानों को लोड करने के लिए कॉल केवल 1 ऑब्जेक्ट की बजाय आकार 4 (सभी समान ऑब्जेक्ट) की सूची लौटाएगा ।

क्या इसका समाधान करने के लिए कोई साफ और आसान तरीका है या व्यवहार अपेक्षित है?

// Parent class is a @MappedSuperclass which may or may not be relevant to the issue 
@Entity 
public class MyClass extends ParentClass { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 

    @ElementCollection(fetch=FetchType.EAGER) 
    @IndexColumn(name="indexColumn") 
    private List<String> collectionOfStrings; 

    // other instance variables, constructors, getters, setters, toString, hashcode and equals 
} 

public class MyClassDAO_Hibernate extends GenericHibernateDAO<MyClass, Long> implements MyClassDAO { 

    @Override 
    public List<MyClass> loadAll() { 
     List<MyClass> entityList = null; 
     Session session = getSession(); 
     Transaction trans = session.beginTransaction(); 
     entityList = findByCriteria(session); 
     trans.commit(); 
     return entityList; 
    } 

} 

protected List<T> findByCriteria(Session session, Criterion... criterion) { 
    Criteria crit = session.createCriteria(getPersistentClass()); 
    for (Criterion c : criterion) { 
     crit.add(c); 
    } 
    return crit.list(); 
} 

MyClassDAO myClassDAO = new MyClassDAO_Hibernate(); // in reality, implementation type is determined with a Factory 
... 
List<MyClass> myClassInstances = myClassDAO.loadAll(); 

धन्यवाद, HeavyE

संपादित करें: findByCriteria कॉल गयी।

+0

आप संस्थाओं को कैसे लोड करते हैं? – axtavt

+0

एक्स्टावट, मैंने अपने खोज में जोड़ा है बायक्रिटारिया विधि जिसे मैंने मूल रूप से शामिल करने के लिए उपेक्षित किया था। – HeavyE

उत्तर

8

मुझे यकीन है कि क्या यह एक बग या वैध व्यवहार है नहीं कर रहा हूँ, लेकिन यह DISTINCT_ROOT_ENTITY परिणाम ट्रांसफार्मर लगाने से ठीक किया जा सकता:

protected List<T> findByCriteria(Session session, Criterion... criterion) { 
    Criteria crit = session.createCriteria(getPersistentClass()); 
    for (Criterion c : criterion) { 
     crit.add(c); 
    } 
    crit.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 
    return crit.list(); 
} 
+0

पूरी तरह से काम किया - धन्यवाद! – HeavyE

2

यह सूची का सही व्यवहार है। सूची ऑब्जेक्ट्स के डुप्लिकेशन को अनुमति देती है और यही वजह है कि आपको अनुक्रमित कॉलम की आवश्यकता है।

सेट एक संग्रह है, जिसमें कोई आइटम एक बार से अधिक होता है:

यह सामान्य संग्रह प्रकार है जो हाइबरनेट से मैप किया जा सकता है। यह मेरे अनुभव में सबसे आम लगातार संग्रह प्रकार है।

थैला एक colleciton जिसमें आइटम एक बार से अधिक हो सकती है: वे बहुत अक्षम हैं क्योंकि हाइबरनेट करता है, तो आइटम आप इसे में डाल दिया उस में लोगों को पहले से ही (यह मानते हुए कि वे बराबर हैं) के रूप में ही कर रहे हैं नहीं बता सकता, इसलिए इसे पूरे संग्रह को हटाना होगा और इसे स्मृति से फिर से सहेजना होगा।

सूची एक अनुक्रमित बैग है। इंडेक्स हाइबरनेट को यह बताता है कि कोई विशेष इन-मेमोरी ऑब्जेक्ट बराबर ऑन-डीबी ऑब्जेक्ट जैसा ही है, इसलिए पूर्ण डिलीट/री-डालने की आवश्यकता नहीं है।

मानचित्र एक सूची की तरह है, सिवाय इसके कि सूचकांक को एक संगणनीय (आमतौर पर अनुक्रमिक) पूर्णांक नहीं होना चाहिए, यह कुछ भी हो सकता है, यहां तक ​​कि एक और वस्तु भी हो सकती है।

तो आपके मामले में मैं आपको सेट का उपयोग करने की सलाह देता हूं।

+2

दुर्भाग्य से, एक सेट का उपयोग इस वर्ग के लिए काम नहीं करेगा - एक सूची आवश्यक है क्योंकि यह एक आदेशित संग्रह है। स्पष्टीकरण के लिए, मुद्दा यह नहीं है कि सूची 'संग्रह OfStrings' में डुप्लीकेट होते हैं लेकिन सूची 'myClassInstances' में डुप्लीकेट होते हैं। – HeavyE

2

यह देखा गया है कि केवल जब संग्रह बेसब्री से प्राप्त किए गए है। हाइबरनेट इस एनोटेशन मैपिंग को बाहरी जॉइन क्वेरी में अनुवादित करता है, जो प्रत्येक लिंक किए गए संग्रहऑफस्ट्रिंग तत्व के लिए मूल तत्व सूची में एकाधिक का कारण बनता है।

इस सटीक समस्या के लिए हाइबरनेट ओआरएम समस्या ट्रैकर में टिकट HHH-6783 देखें। और जाहिर है कोई समाधान नहीं। :-(

एक लिंक to the Hibernate FAQ कि बाहरी में शामिल होने के भी यहां प्रदान की जाती है के साथ मुद्दों में चला जाता है।

मैं ठीक उसी मुद्दे से निपटने कर रहा हूँ। का उपयोग करते हुए एक @ElementCollection मेरे मामले में समझ में आता है, लेकिन कम से नहीं मेरे सभी डेटा एक्सेस लेयर कार्यान्वयन की समीक्षा करने की लागत। क्या करना है?

+0

इसे एचएचएच -6783 में एक बग के रूप में चिह्नित नहीं किया गया है, लेकिन यह मेरे लिए एक बग की तरह बहुत गंध करता है। मैंने अपने उपयोग के मामले में Hibernate.initialize() के साथ LAZY का सहारा लिया क्योंकि केवल कुछ ऑब्जेक्ट लौटाए गए हैं और एन + 1 प्रश्न ठीक हैं। –