2012-01-25 15 views
13

का उपयोग करने के लिए अंतर्निहित जुड़ने के लिए कैसे मजबूर करें Offer है जिसमें वैकल्पिक कक्षा Article से संबंधित संबंध है। ताकि कुछ आलेख संपत्ति प्रदान करता है null मान रखता है।हाइबरनेट/जेपीए: बाएं बाहरी जॉइन

यदि मैं निम्नलिखित कथन का उपयोग करता हूं, तो सब कुछ ठीक काम करता है। मुझे सभी ऑफ़र मिल गए, यहां तक ​​कि जिनके पास कोई आलेख नहीं है।

SELECT o FROM Offer o 
     LEFT OUTER JOIN o.article a 
     LEFT OUTER JOIN o.vendor v 
     WHERE v.number = '0212' OR o.article.nummer = '123456' 

मैं केवल इन लेखों NULL से अलग होने के ऑफर मिल गया:

SELECT o FROM Offer o 
     LEFT OUTER JOIN o.article a 
     LEFT OUTER JOIN o.vendor v 
     WHERE v.number = '0212' OR a.nummer = '123456' 

तो मैं बयान के बदल जाते हैं। ऐसा इसलिए है क्योंकि अंतर्निहित के लिए संकेत (o.article.nummer) एक आंतरिक शामिल होने को मजबूर करता है।

क्या अंतर्निहित जॉइन (एनोटेशन संचालित या कुछ और) में बाएं बाहरी जुड़ने को मजबूर करने की संभावना है? यदि मैं इस तरह एक संक्षिप्त रूप इस्तेमाल कर सकते हैं एक मौका है:

SELECT o FROM Offer o 
     WHERE v.number = '0212' OR o.article.nummer = '123456' 

उत्तर

3

आप अनुच्छेद संपत्ति पर @Fetch(FetchMode.JOIN) डालने की कोशिश कर सकते हैं। हालांकि, यह एक हाइबरनेट एनोटेशन है।

import org.hibernate.annotations.Fetch; 
import org.hibernate.annotations.FetchMode; 

//... 

@ManyToOne 
@Fetch(FetchMode.JOIN) 
Article article; 
+0

मेरे लिए इस समस्या को हल नहीं किया! –

+0

मुझे नहीं पता कि यह समस्या को कैसे हल करना चाहिए।AFAIK Fetchmode केवल निर्दिष्ट करता है कि ऑब्जेक्ट को स्मृति में प्रारंभ करने के लिए डेटा कैसे प्राप्त करें, क्वेरी में शामिल होने के तरीके के बारे में नहीं। –

1

जहां तक ​​मेरा खुदाई कर सकता है, हाइबरनेट प्रस्ताव संघ एक HQL क्वेरी के लिए शामिल होने के डिफ़ॉल्ट निहित प्रपत्र को बदलने के तरीके नहीं करता है।

सबसे अच्छा समाधान मैं खुद के लिए मिल सकता है इस प्रकार थे:

  • स्पष्ट जानकारी में शामिल होने के साथ क्वेरी का निर्माण;
  • मानदंड का प्रयोग करें, जो गतिशील क्वेरी बिल्डिंग के लिए शायद सबसे अच्छा है।
+0

ओपी ने यह नहीं कहा कि गतिशील कुछ भी है। क्या मैं कुछ भुल गया? –

+0

'0212' और '123456' उपयोग रन टाइम पर क्वेरी परिवर्तनों का सुझाव देते हैं। "सही SQL जुड़ने के उपयोग" के लिए मिले समाधानों में से एक इसके बजाय मानदंड API का उपयोग कर रहा था। और यह अधिक प्राकृतिक लगता है। –

+0

मानदंड एपीआई आमतौर पर उपयोग करने के लिए अधिक जटिल है और एचक्यूएल के रूप में कम शक्तिशाली है। यदि केवल मान बदलते हैं, तो क्वेरी में पैरामीटर डालें। यह वास्तव में "गतिशील" नहीं है, यह parametrized है। –

0

सबसे पहले यदि आप a.nummer के बजाय o.article.nummer का उपयोग करने का प्रयास करते हैं तो मेरा मानना ​​है कि यह एक आंतरिक उपस्थिति के साथ एक अतिरिक्त WHERE खंड में डाल देगा। स्पष्ट रूप से बाएं जुड़ने के लिए थ्रे का कोई तरीका नहीं है। लेकिन आप स्वयं को क्वेरी में स्वयं निर्दिष्ट कर रहे हैं, इसलिए उपरोक्त ए। Number = '23456' से जुड़ी इकाई का उपयोग करें।

चूंकि आप जानते हैं कि फ़ील्ड शून्य है, आप इसका उपयोग नहीं कर सकते हैं = जैसे आप शून्य में फ़ील्ड पर SQL में उपयोग नहीं कर सकते हैं। इसके बजाय इस उद्देश्य के लिए एक रिक्त स्ट्रिंग पर शून्य मान परिवर्तित करने के लिए COALESCE का उपयोग करें:

SELECT o FROM Offer o 
    LEFT OUTER JOIN o.article a 
    LEFT OUTER JOIN o.vendor v 
     WHERE v.number = '0212' 
     OR COALESCE(a.nummer,'') = '123456' 
0

मैं एक समान समस्या थी: मैं जो एक स्तंभ SpecificType निहित GeneralFacility -Table किसी प्रकार का था। सभी सुविधाओं में इस प्रकार की सुविधा नहीं थी और जैसा कि विशिष्ट प्रकार के भीतर सामान्य विशिष्टता के बिना सामान्य प्रकार की आंतरिक प्रविष्टि में शामिल हो गया था, तालिका के नीचे एक विशिष्ट प्रकार के बिना गिर गया।

मैं मॉडल में

@Fetch(FetchMode.SELECT) 

अगले डाल @ManyToOne लाइन करने के लिए से समस्या हल हो। प्रकार अब एक अलग प्रश्न में लाया जाता है और यदि वह कुछ भी वापस नहीं करता है तो सामान्य सुरक्षा-क्वेरी के परिणाम अस्वीकार नहीं किए जाते हैं।

+0

मुझे लगता है कि यह केवल तभी लागू होता है जब आप इकाई को प्राप्त करते हैं उदा। 'session.get' का उपयोग कर। जब आपको किसी HQL क्वेरी में संपत्ति की आवश्यकता होती है, तब तक इसका कोई प्रभाव नहीं पड़ता है जहां तक ​​मुझे पता है। –

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