2011-08-24 4 views
5

समस्या यह है कि मेरे पास मेरी इकाई में दो बैग हैं जो मैं अपने जेएसएफ फ्रंटएंड में दिखाना चाहता हूं (पीछे की ओर वसंत नहीं, इसलिए आलसी लोडिंग नहीं)।हाइबरनेट लाने में शामिल हों -> एकाधिक बैग नहीं ला सकते हैं

  • प्वाइंट 1 (लेबल 1, लेबल 2) (tag1 ... टैग एन)
  • प्वाइंट 2 (लेबल 3, लेबल: तो मैं बेसब्री से इस प्रकार की सूची में जानकारी प्रदर्शित करने के लिए उन्हें लाने के लिए है 4) (टैग 1 ... टैग एन)

दोनों सूचियों को उत्सुक करने के लिए काम नहीं किया। तो मैंने एक भाग लेने के साथ मेरी किस्मत आजमाया। यह मुझे एक सूची लाने की इजाजत देता है, लेकिन जब मैंने दूसरी सूची जोड़ दी तो मुझे ज्ञात "एकाधिक बैग नहीं मिल सकता" त्रुटि मिलती है।

क्या हाइबरनेट एक क्वेरी में दो fetch joins को संभाल सकता है?

public class PointOfInterest 
@OneToMany(mappedBy="poi") 
private List<PointOfInterestLabel> labels = new ArrayList<PointOfInterestLabel>(); 

@ManyToMany 
private List<Tag> tags = new ArrayList<Tag>(); 

मेरी लाने में शामिल होने:

Caused by: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags 
    at org.hibernate.loader.BasicLoader.postInstantiate(BasicLoader.java:94) 
    at org.hibernate.loader.hql.QueryLoader.<init>(QueryLoader.java:123) 
    at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206) 
    at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136) 
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101) 
    at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80) 
    at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:98) 
    at org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:557) 
    at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:422) 
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1385) 
    at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:954) 
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:883) 
    ... 55 more 

उत्तर

5

जवाब है::

SELECT DISTINCT p from PointOfInterest p 
     left join fetch p.labels 
     left join fetch p.tags WHERE p.figure = :figure 

स्टार्टअप पर मेरी हाइबरनेट कारखाने के निर्माण के साथ विफल रहता है कोई। यह इसे संभाल नहीं सकता है। यही वह कहता है।

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

आमतौर पर यह भी समझ में नहीं आता है। यदि आप एक टेबल से पूछते हैं और शुरुआती तालिका में 10 रिकॉर्ड प्राप्त करते हैं, पहले बैग में 10 और दूसरे बैग में 10 अन्य, आप स्मृति में इन 30 ऑब्जेक्ट्स को बनाने के लिए केवल 1000 रिकॉर्ड्स पुनर्प्राप्त करेंगे। प्रत्येक तालिका में 100 रिकॉर्ड होने पर रिकॉर्ड की संख्या की कल्पना करें (संकेत: 300 के बजाय 1,000,000) और जब आप किसी अन्य बैग (संकेत: 400,000 के बजाय 100,000,000) में शामिल होते हैं ...

वैसे: fetch में शामिल हों अजीब प्रभाव और समस्याओं का कारण बन सकता है और इससे बचा जाना चाहिए, सिवाय इसके कि आप वास्तव में जानते हैं कि आप क्या कर रहे हैं।

+0

धन्यवाद! इस पल के लिए मैंने इसे सेट के साथ बदल दिया, लेकिन मुझे लगता है कि मैं कल इंटरफेस को दोबारा कर दूंगा और कम जानकारी प्रदर्शित करूंगा। प्रतिक्रिया के लिए धन्यवाद! जब आप अपने अग्रभाग में कोई दृढ़ता का दायरा नहीं रखते हैं तो आप इसे कैसे हल करेंगे। प्राप्त इकाइयों के बजाय डीएओ में निर्मित डेटा ट्रांसफर ऑब्जेक्ट्स का उपयोग करें? मैंने परियोजना को विरासत में मिला और मुझे बड़ी डिजाइन में बदलाव करने की अनुमति नहीं है, न ही मुझे इसे j2ee पर स्विच करने की अनुमति है। : -/ – mkuff

+0

आप आलसी लोडिंग बंद कर सकते हैं, जो प्रदर्शन के लिए खराब है। यह तुरंत अलग प्रश्नों से बैग लाता है। लोडिंग को मजबूर करने के लिए आप बैग (जैसे आकार) तक पहुंच सकते हैं। सही समाधान दाओ के बाहर सत्र बनाना और इसे पूरे व्यापार लेनदेन के लिए रखना है। (दाओ को प्रत्येक कॉल में एक सत्र बनाना सत्र-प्रति-कॉल कहा जाता है और यह एक विरोधी पैटर्न है।) –

+0

तो वास्तव में यह एक पकड़ 22 समस्या है: यदि आप शामिल होने का उपयोग नहीं करते हैं, तो आपको एन + 1 समस्या मिलती है या आलसी प्रारंभिक अपवाद। दाओ के बाहर सत्र एक हैक है, सबसे पहले क्योंकि यह जेपीए अनुबंध के पास कहीं भी नहीं है और दूसरा यह है क्योंकि यह शायद ही नियंत्रित है, क्योंकि आपको उस समय एक इकाई के जीवनकाल पर कोई धारणा नहीं लेनी चाहिए, जहां आप इसे बनाते हैं। यह कई अनुरोधों पर फैल सकता है, जरूरी नहीं कि http। – Deroude

1

सेट का उपयोग करने के बजाय, आप क्वेरी को विभाजित कर सकते हैं और विभिन्न प्रश्नों में इकाइयों को लोड कर सकते हैं।
जैसे

From PointOfInterest p left join fetch p.labels WHERE p.figure = :figure 
    From PointOfInterest p left join fetch p.tags WHERE p.figure = :figure    

देखें the link

संबंधित मुद्दे