2012-03-27 12 views
41

मेरे पास 2 इकाइयां हैं, A और B। वे संबंधित हैं लेकिन मैं सेम में संबंध मैपिंग जोड़ना नहीं चाहता हूं।एचक्यूएल अन-संबंधित इकाइयों में शामिल हो गया

हम का उपयोग कैसे कर सकते हैं A और B के बीच एचक्यूएल या मानदंड का उपयोग कर बाहरी बहिष्कार?

कुछ समाधान इस के लिए उपलब्ध नहीं है,

  1. उपयोग मूल निवासी एसक्यूएल here बताया के रूप में।
  2. एक रिश्ते जोड़ें और का उपयोग करें ए से एक बाएं ए.बी में शामिल हों।
  3. हम एक एक, बी बी जहां a.some = b.some

मैं हमेशा वापस इन 2 विकल्प जा रहा था से * एक भीतरी चयन के रूप में HQL में में शामिल होने के लिए कर सकते हैं, वहाँ है इसके लिए कोई विकल्प? या यह संभव नहीं है?

उत्तर

51

वर्तमान में, एचटीएल का उपयोग करते हुए खंड में असंबद्ध वर्गों में शामिल होने पर थीटा-शैली केवल आंतरिक जुड़ने का समर्थन करती है।

request बाहरी समर्थन करने के लिए ऐसी स्थिति के लिए शामिल होने के currently the 3-rd most voted enhancement है लेकिन मुझे नहीं लगता इस सुविधा निकट भविष्य में लागू किया जाएगा है के रूप में यह re-implementation of the current ANTLER-based query parser पहले जो एक विशाल कार्य IMO प्रतीत हो रहा है की आवश्यकता है।

आप बाईं शामिल होने के प्रदर्शन करने के लिए HQL उपयोग करने के लिए ए और बी के बीच संबंधों को जोड़े बिना जोर देते हैं, तो आप भीतरी करने के लिए विकल्प 3 का उपयोग शामिल होने के पहले, उसके बाद निम्न HQL का उपयोग कर सकते

from A a where a.some not in (select b.some from B) 

को खोजने के लिए उन सभी ए को बाहर निकालें जो बी में शामिल नहीं हो सकते हैं और परिणामों को प्रोग्रामेटिक रूप से जोड़ सकते हैं।

अद्यतन

रिलीज 5.1.0 के रूप में HHH-16 (Explicit joins on unrelated classes) तय हो गई है और हम असंबंधित संस्थाओं में शामिल होने के लिए सक्षम होना चाहिए।

+1

क्रिस्टल तेज। धन्यवाद! –

+0

क्या आप नए "शामिल हों" विकल्प के वाक्यविन्यास के स्रोत को इंगित कर सकते हैं? मैंने ए.एक्स = बी.ई. पर एक बाएं जॉइन बी बी से चयन करने की कोशिश की और अभी भी 'org.hibernate.hql.internal.ast.QuerySyntaxException: पथ में शामिल होने की उम्मीद है!'। (मैंने 'हाइबरनेट-कोर' संस्करण 5.1.0 जोड़ा। मेरे मैवेन पोम फ़ाइल के लिए अंतिम, अन्य कलाकृतियों को मेरे पुराने संस्करणों में होना चाहिए। लेकिन जैसा कि मैंने पढ़ा [एचएचएच -16] (https://hibernate.atlassian.net/projects/ एचएचएच/मुद्दों/एचएचएच -16? फिल्टर = allissues और orderby = वोट + डीईएससी% 2 सी + प्राथमिकता + डीईएससी% 2 सी + अद्यतन + डीईएससी), यह पर्याप्त होना चाहिए।) – Joe7

+0

अद्यतन के लिए धन्यवाद और बंद मुद्दे पर सूचक। –

0

बोल्ड स्टेटमेंट: आप नहीं कर सकते।

क्यों? जेपीक्यूएल (और एचक्यूएल) उनसे जुड़ने के लिए इकाइयों के बीच एक पथ की अपेक्षा करता है।

क्या मैं आमतौर पर (पसंदीदा क्रम) की इस तरह एक स्थिति में कार्य करें:

  1. एसोसिएट संस्थाओं।
  2. प्रोग्राम को प्रोग्रामेटिक रूप से इकट्ठा करने के लिए आवश्यक डेटा प्राप्त करें।
  3. आपके द्वारा पहले से उल्लिखित तीन विकल्पों में से 1 या 3 या तो।
+2

इस जवाब में नई जानकारी क्या है? मैंने प्रश्न में इन विकल्पों का पहले से ही उल्लेख किया है और मैं उनका उपयोग नहीं करना चाहता हूं। ** उनसे जुड़ने के लिए संस्थाओं के बीच एक पथ की अपेक्षा करता है ** गलत है यदि आप कोई सहयोग नहीं करते हैं तो भी आप आंतरिक भागीदारी कर सकते हैं। – ManuPK

+0

मेरी माफ़ी। यही कारण है कि मैंने कहा कि यह एक बोल्ड स्टेटमेंट था। केवल स्पष्ट करने हेतु। यदि आपका मतलब है कि एक क्रॉस शर्तों के साथ जुड़ना (जैसे दो जड़ें) एक ही चीज़ को प्राप्त करने के लिए एक ही चीज़ प्राप्त करने के लिए हाँ, तो इसकी अनुमति है। असल में शामिल होना (रूट.जॉइन (...)) एक अलग जानवर है और यही वह है जो आपको अपने लक्ष्य को प्राप्त करने के लिए, या एचक्यूएल समतुल्य है। मुझे अब तक इस समस्या का समाधान नहीं मिला है। इस प्रकार मेरा जवाब: आप नहीं कर सकते। ध्यान दें कि मुझे यहां सुधारने के लिए प्यार करना अच्छा लगेगा! –

3

केन चैन ने कहा, आप इसे सीधे एक एकल एचक्यूएल क्वेरी में नहीं कर सकते हैं।

के संबंध में अपने तीन संभावनाएं:

  1. मूल निवासी एसक्यूएल: सिफ़ारिश लायक नहीं। बाहरी जोड़ों के लिए वाक्यविन्यास विभिन्न डेटाबेस के बीच काफी अलग है।
  2. एक रिश्ता जोड़ें: यही वह है जो मैं करूँगा। इसका अधिक कोड या स्मृति खर्च नहीं होता है और इसे जल्दी से प्रोग्राम किया जाता है।
  3. आंतरिक शामिल हों: यदि कनेक्शन वास्तव में डेटाबेस में बाहरी शामिल होता है तो यह काम नहीं करता है (गायब पंक्तियां)।

तुम सच में संबंध जोड़ने के लिए नहीं करना चाहते हैं किसी विशेष कारणों से हैं, तो आप क्वेरी दो व्यक्तिगत क्वेरी में उदाहरण के लिए इस तरह विभाजित है और जावा में मैन्युअल रूप से परिणाम शामिल हो सकते हैं,:

Query qa = session.createQuery("from A a"); 
List la = qa.list(); 

Query qb = session.createQuery("select distinct b.* from B b, A a where a.some=b.some"); 
List lb = qb.list(); 

Map bMap = new HashMap(); 
for (B b : lb) { 
    bMap.put(b.getId(), b); 
} 

/* example with for loop */ 
for (A a : la) { 
    B b = bMap.get(a.getForeignKeyForB()); 
    /* now you have A a and the outer joined B b and you can do with them what you want */ 
    ... 
} 

इस समाधान में (लगभग) निष्पादन समय और स्मृति में समान लागत है क्योंकि बाहरी डेटाबेस (समाधान 2.) में शामिल होता है। यह सिर्फ थोड़ा और जावा कोड है।

(समाधान केन चान द्वारा प्रस्तावित है कि एक के समान है, लेकिन यह "नहीं में" और भीतरी का चयन करें, जो दोनों डेटाबेस में अक्षम हो सकता है बचा जाता है।)

1

आप जानते हैं कि के लिए हर हैं एक अधिकतम 1 बी है, आप एक सबक्वायरी का भी उपयोग कर सकते हैं।

उदाहरण के लिए:

select a, (select b from B b where b.some = a.some) 
from A a 

क्या आप जानते हैं कि वहां मौजूद कम से कम 1 बी, आप भी निम्न क्वेरी का उपयोग कर सकते हैं, लेकिन यह अनुशंसित नहीं है कि यह एक हैक है के रूप में हैं:

select a, (select b4 from B b4 where b4=b and b4.some=a.some) from A a, B b 
where a.some=b.some or (a.some not in (select b2.some from B b2) 
and b.id = (select min(b3.id) from B b3)) 
+0

वाह आपको बहुत धन्यवाद ... इसने 3 दिनों के लिए खोज करने के बाद मेरी समस्या हल की! – kaiser

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