2009-02-26 12 views
13

मेरे पास निम्न इकाई संरचना है: व्यवसाय -> अभियान -> प्रचार, जहां एक व्यवसाय में कई अभियान हो सकते हैं और एक अभियान में कई प्रचार हो सकते हैं। एक से कई संबंधों को लाज़ी के रूप में घोषित किया जाता है। मेरे कोड में एक ही स्थान पर, मैं बेसब्री से एक व्यापार से दोनों संग्रह लाने के लिए की जरूरत है, तो मैं कार्य करें:जेपीए: कृपया "fetch में शामिल होने" को समझने में सहायता करें

Query query = entityManager.createQuery("select b from Business b " + 
      "left join fetch b.campaigns c " + 
      "left join fetch c.promotions where b.id=:id"); 
query.setParameter("id", b.getId()); 
business = (Business) query.getResultList().get(0); 

हालांकि, क्वेरी एक परिणाम सूची है कि यह में 4 बिजनेस वस्तुएं शामिल हैं, सभी 4 वस्तुओं की बात कर रहे रिटर्न वही व्यवसाय उदाहरण। मेरे डेटाबेस में, इस व्यवसाय के तहत 3 अभियान हैं, और सभी 3 अभियानों में उनके तहत 3 प्रचार हैं।

मैं दो प्रश्न हैं:

  1. सबसे पहले, मैं का उपयोग सूची संबंधों के कई पक्षों को समाहित करने के लिए, लेकिन जब कार्यक्रम चलाता है, मैं "org.hibernate.HibernateException: एक साथ कई बैग को नहीं लाया जा सकता है "अपवाद। तब मैंने इस अपवाद को गुमराह किया और ऐसा लगता है कि मुझे सूची के बजाय सेट का उपयोग करना है। तो मैंने संग्रह को सेट करने के लिए बदल दिया और यह काम किया। क्या कोई मुझे बता सकता है कि इस स्थिति में सूची क्यों काम नहीं करेगी?

  2. मैं क्वेरी को एक परिणाम वापस करने की उम्मीद कर रहा हूं, क्योंकि यह आईडी के खिलाफ पूछताछ कर रहा है, जो प्राथमिक कुंजी है और इस प्रकार केवल एक ही परिणाम लौटा देना चाहिए। लेकिन यह पता चला है कि यह एक सूची में 4 उदाहरण देता है। क्या ये एक दिक्कत है? या यह अपेक्षित व्यवहार है?

किसी भी मदद की सराहना की जाएगी।

उत्तर

20

उत्पन्न एसक्यूएल कुछ ऐसा दिखाई देगा:

select * from Business b 
left outer join campaigns c on c.business_id = b.id 
left join promotions p on p.campaign_id = c.id 
where b.id=:id 

आंतरिक हाइबरनेट में केवल एक व्यवसाय उदाहरण होगा, हालांकि डुप्लीकेट परिणाम सेट में संरक्षित किए जाएंगे। यह व्यवहार की उम्मीद है। व्यवहार की आवश्यकता DISTINCT खंड का उपयोग करके या तो प्राप्त किया जा सकता है, या परिणामों को फ़िल्टर करने के लिए एक LinkedHashSet का उपयोग करके:

Collection result = new LinkedHashSet(query.getResultList()); 

जो केवल अद्वितीय परिणाम दिखाएँगे, प्रविष्टि आदेश में संरक्षण।

"org.hibernate.HibernateException: एक साथ कई बैग नहीं ला सकता" जब भी आप उत्सुकता से आदेशित फैशन (और संभवतः डुप्लीकेट आइटम) में एक से अधिक संग्रह लाने की कोशिश करते हैं। यदि आप जेनरेट किए गए SQL पर विचार करते हैं तो यह समझ में आता है। हाइबरनेट के पास यह जानने का कोई तरीका नहीं है कि क्या डुप्लीकेट ऑब्जेक्ट में शामिल है या बच्चे तालिका में वास्तविक डुप्लिकेट डेटा द्वारा किया गया था। एक अच्छी व्याख्या के लिए this पर देखें।

+1

क्वेरी में "विशिष्ट" जोड़कर चाल चल रही है। धन्यवाद। –

1
  1. यदि आप एक सूची का उपयोग मुझे लगता है, हाइबरनेट मानता है कि क्रम महत्वपूर्ण है, और यह पंक्तियों से तत्वों का क्रम लौटे निकालना होगा, लेकिन अगर आप एक nother तालिका हाइबरनेट साथ शामिल प्रत्येक अभियान कई मिल जाएगा समय जो हाइबरनेट को भ्रमित करता है। फिर से, मैं सिर्फ इस

  2. यह अपेक्षित व्यवहार संभालने हूँ एकल रूट इकाई पाने के लिए एक RootEntityResultTransformer का उपयोग करें: http://www.hibernate.org/hib_docs/v3/api/org/hibernate/transform/RootEntityResultTransformer.html

3
  1. सूची कार्तीय उत्पाद की वजह से अनावश्यक तत्वों हो सकता है और लोगों की है कि के बारे में पता नहीं थे, इसलिए हाइबरनेट लोग इस त्रुटि फेंक लोग इस समस्या से बचने के सूची के बजाय सेट का उपयोग करने के लिए मजबूर करने के लिए शुरू कर दिया। स्रोत 1
0

सेट का उपयोग करने के बजाय एक और कामकाज डेटा प्राप्त करने के लिए दो प्रश्नों का उपयोग करना है: - पहला अभियान और व्यापार के संबंधित प्रचार को लोड करने के लिए। फिर लाने के लिए व्यवसाय और उसके अभियानों को

Query query1 = entityManager.createQuery("select c from Business b join b.campaigns c left join fetch c.promotions where b.id=:id"); 
    query1.setParameter("id", b.getId()); 
    query1.getResultList(); 

    Query query2 = entityManager.createQuery("select b from Business b left join fetch  b.campaigns where b.id=:id"); 
    query2.setParameter("id", b.getId()); 
    business = (Business) query2.getResultList().get(0); 
संबंधित मुद्दे