2012-05-19 9 views
5

मैं HQLके विभिन्न संयोजनों की कोशिश कर दिया गया है और मानदंड और मैं कुछ अनावश्यक मिलती (दोनों में) से बचने के लिए नहीं कर पाए हैं और कुछ अनावश्यक कैसे (मानदंड में) का चयन करता है।अनावश्यक चयन से बचने और HQL और मानदंड में मिलती है

हमारे परिदृश्य में, हम सेगमेंट और आवेदन संस्थाओं (नेविगेशन अनुप्रयोग के लिए सेगमेंट से है) के बीच एक @ManyToMany रिश्ता है।

select 
    this_.id as id1_1_, 
    this_.description as descript2_1_1_, 
    this_.name as name1_1_, 
    applicatio3_.segment_id as segment1_1_, 
    applicatio1_.id as app2_,    <==== unnecessary APPLICATIONS columns 
    applicatio1_.id as id7_0_, 
    applicatio1_.name as name7_0_, 
    applicatio1_.accountId as accountId7_0_, 
    applicatio1_.applicationFlags as applicat5_7_0_, 
    applicatio1_.description_ as descript6_7_0_, 
from 
    SEGMENTS this_ 
inner join 
    SEGMENTS_APPLICATIONS applicatio3_ 
     on this_.id=applicatio3_.segment_id 
inner join          <==== unnecessary join 
    APPLICATIONS applicatio1_ 
     on applicatio3_.app_id=applicatio1_.id 
where 
    applicatio1_.id = ? 

आप देख सकते हैं, मानदंड अनुप्रयोग, है जो मैं नहीं करना चाहता से स्तंभ का चयन करता है:

Application app = ... 
List<Segment> segments = session.createCriteria(Segment.class) 
    .createCriteria(Segment.APPLICATIONS) 
    .add(Restrictions.idEq(app.getId())) 
    .list(); 

Wich इस एसक्यूएल का उत्पादन:

सबसे पहले मैं की कोशिश की इस मानदंड चुना जाना है। मुझे ऐसा करने का कोई रास्ता नहीं मिला है (क्या यह संभव है?)। इसके अलावा, यह आवेदन के साथ जुड़ता है, जो मुझे लगता है कि आवश्यक नहीं है क्योंकि एप्लिकेशन आईडी पहले से ही तालिका में शामिल है SEGMENTS_APPLICATIONS (यह एचक्यूएल के साथ होता है)।

(एक अतिरिक्त संदेह के रूप में, मैं एक प्रतिबंध को जानना चाहता हूं जो ऐप का उपयोग सीधे करता है, न कि app.getId()। जैसा कि आप देखेंगे, मैं क्वेरी के एचक्यूएल संस्करण में ऐसा कर सकता हूं)

जब से मैं चयन हिस्सा (मैं आवेदन गुण की जरूरत नहीं है) मैं "का चयन करें" खंड के साथ इस HQL की कोशिश की सीमा नहीं कर सकता:

Application app = ... 
List<Segment> segments = session.createQuery(
    "select s from Segment s join s.applications as app where app = :app") 
    .setParameter("app", app) 
    .list(); 

जो पैदा करता है:

select 
    segment0_.id as id1_, 
    segment0_.description as descript2_1_, 
    segment0_.name as name1_, 
from 
    SEGMENTS segment0_ 
inner join 
    SEGMENTS_APPLICATIONS applicatio1_ 
     on segment0_.id=applicatio1_.segment_id 
inner join          <==== unnecessary join 
    APPLICATIONS applicatio2_ 
     on applicatio1_.app_id=applicatio2_.id 
where 
    applicatio2_.id=? 

आप देख सकते हैं एचक्यूएल ("चयन एस" भाग के लिए धन्यवाद) से गुणों का चयन नहीं करता है, लेकिन अभी भी आवेदन तालिका में शामिल है, जो मुझे लगता है कि अनावश्यक है। हम इससे कैसे बच सकते हैं?

(एक तरफ ध्यान दें के रूप में, आप देखते हैं कि HQL में मैं एप्लिकेशन सीधे नहीं की तरह मानदंड में इस्तेमाल कर सकते हैं, और app.getId())

आप मदद कृपया मुझे एक तरह से "चयन" से बचने के लिए मिल सकता है मानदंड और अनावश्यक दोनों मानदंड और एचक्यूएल में "जुड़ता है"?

(यह उदाहरण @ManyToMany के साथ है, लेकिन मुझे लगता है कि यह @OneToMany के साथ भी होता है और @ManyToOne और @OneToOne के साथ भी fetch = LAZY के साथ भी होता है)।

आपको बहुत बहुत धन्यवाद, Ferran

उत्तर

5

मानदंड का उपयोग करते समय अतिरिक्त चयनित कॉलम लंबे समय से bug in Hibernate से आते हैं। AFAIK, इससे बचने का एकमात्र तरीका एचक्यूएल, या जेपीए 2 मानदंड एपीआई का उपयोग करना है।

अन्य समस्या को a bug के रूप में भी संकेत दिया गया है, लेकिन इसका कम प्रभाव पड़ता है, और मुझे इसके बारे में अधिक परवाह नहीं है।

+0

वाह, बहुत बहुत धन्यवाद। एक लंबे समय से बग? मुझे विश्वास नहीं है कि उन्होंने अभी तक इसे ठीक नहीं किया है। सिर्फ इसलिए कि एचक्यूएल के साथ कामकाज है? –

+0

मैं इसे या तो विश्वास नहीं कर सकता :-(ओटीओएच, यह ओपन-सोर्स सॉफ़्टवेयर है, और वे शायद नए जेपीए 2 मानदंड कार्यान्वयन को लागू करने में व्यस्त थे, जिसे शायद इस पुराने मालिकाना एपीआई पर प्राथमिकता दी जानी चाहिए। –

+0

ओह, तो क्या आप हमें सलाह देंगे पुराने मानदंड एपीआई के बजाय जेपीए 2 का उपयोग शुरू करने के लिए? दोनों को मिश्रित किया जा सकता है? (बस पुराने कोड के रिफैक्टरिंग से बचने के लिए)। –

-2

प्रश्न क्या है? यदि यह नहीं हो रहा तो से शामिल होने के लिए मजबूर करने के लिए कैसे LINQ http://msdn.microsoft.com/en-us/magazine/ee336024.aspx

और Compiled LINQ joins

precompiling पर लेख पढ़ें अन्यथा सिर्फ क्वेरी लिखना अपने आप को और स्पष्ट रूप से शामिल होने के वहाँ नहीं होगा है ....

+0

प्रश्न यह है कि मानदंड में आवेदन का चयन कैसे करें और आवेदन मानदंड और एचक्यूएल दोनों में शामिल हों। हम हाइबरनेट का उपयोग कर रहे हैं। –

+0

हां, यह विजुअल स्टूडियो के साथ आता है। इसमें समान संरचनाएं होनी चाहिए। – Jay

+0

(मैंने "LINQ एक और ओआरएम है" हटा दिया है लेकिन अब मैं इसे वापस नहीं रख सकता) –

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