2010-06-29 8 views
5

मैं वर्तमान में जेपीए हाइबरनेट को EclipseLink का उपयोग करने से एक (कार्य) एप्लिकेशन को चलती हूँ, ज्यादातर यह काफी आसानी से चला गया, लेकिन मैं कर सकते हैं एक बात है कि मैं व्याख्या नहीं कर सकते खोजने कर रहा हूँ, और भी किसी भी अच्छे खोज शब्द के बारे में सोचो मत!हाइबरनेट जेपीए - ManyToOne संबंध आबादी नहीं

असल में, मैं चार संस्थाओं, एक-से-कई रिश्तों को एक श्रृंखला के गठन के साथ है:

EntityA EntityB की, जिनमें से प्रत्येक EntityC के की एक सूची है, जिनमें से प्रत्येक EntityD के की एक सूची है की एक सूची है

उन लोगों में से

प्रत्येक फिर एक कई-से-एक संबंध अन्य रास्ते पर जा रहा है, तो:

EntityD एक EntityC है, जो एक EntityB है, जो एक EntityA है है है।

है कि (भारी स्पष्टता के लिए कम):

@Entity 
public class EntityA { 
    @OneToMany (cascade = CascadeType.All, mappedBy = "entityA") 
    private List<EntityB> entityBList; 
    ... 
} 

@Entity 
public class EntityB { 
    @OneToMany (cascade = CascadeType.All, mappedBy = "entityB") 
    private List<EntityC> entityCList; 

    @JoinColumn (name = "ENTITY_A", referencedColumnName = "ENTITY_A_ID") 
    @ManyToOne (cascade = CascadeType.PERSIST, optional = false) 
    private EntityA entityA; 
} 

@Entity 
public class EntityC { 
    @OneToMany (cascade = CascadeType.ALL, mappedBy = "entityC") 
    private List<EntityD> entityDList; 

    @JoinColumn (name = "ENTITY_B", referencedColumnName = "ENTITY_B_ID") 
    @ManyToOne (cascade = CascadeType.PERSIST, optional = false) 
    private EntityB entityB; 
} 

@Entity 
public class EntityD { 
    @JoinColumn (name = "ENTITY_C", referencedColumnName = "ENTITY_C_ID") 
    @ManyToOne (cascade = CascadeType.PERSIST, optional = false) 
    private EntityC entityC; 
} 

मैं डेटाबेस से एक EntityA मिल (यह देख ऊपर अपने प्राथमिक कुंजी द्वारा), और इस प्रकार के लिए एक PersistentBag के साथ, एक अच्छी तरह से आबादी EntityA उदाहरण मिल मेरा List<EntityB>। मैं एक आलसी लोड हो रहा है जब मुझे लगता है कि List<EntityB> भिन्नता देखते हैं, और एक ही EntityB से EntityCs प्राप्त करने के लिए बार-बार।

इस बिंदु पर, सबकुछ मुझे उम्मीद है, मेरे पास एक एंटिटीए, बी और सी डेटाबेस से मूल्यों के साथ पूरी तरह से आबादी है, लेकिन फिर मैं एंटीटीसी से अपना एंटिटीडी प्राप्त करने का प्रयास करता हूं, और यह पता चला कि यह शून्य है।

मेरा इकाई प्रबंधक अभी भी इस बिंदु पर खुला और सक्रिय है, और अगर मैं इसे एंटिटीए प्राप्त करने के तुरंत बाद डीबगर में देखता हूं, तो मैं एंटिटीसी तक रिश्तों के माध्यम से चल सकता हूं, और फिर 'इकाई डीलिस्ट' देख सकता हूं 'शून्य के रूप में।

EntityManager.refresh(entityC); 

जो entityDList के लिए एक lazily-लोडेड PersistentBag सहित अपने सभी तत्वों को भरता है:

एकमात्र समाधान मैं अब तक मिल गया है उपयोग करने के लिए है।

तो, मेरा अनुमान है कि हाइबरनेट केवल 2 स्तरों को गहराई से संदर्भित करता है (या 3, आप कैसे गिनते हैं इसके आधार पर), और उसके बाद छोड़ देते हैं, हालांकि मुझे वास्तव में समझ में नहीं आता कि यह क्यों होगा। क्या यह किसी के लिए समझ में आता है?

वहाँ .refresh के अलावा कोई समाधान अन्य है? कुछ प्रकार की कॉन्फ़िगरेशन या एनोटेशन वैल्यू जो हाइबरनेट को संदर्भों को सभी तरह से पॉप्युलेट कर देगा?

+0

हाइबरनेट कॉन्फ़िगरेशन पैरामीटर "max_fetch_depth" के लिए मान सेट क्या है? –

उत्तर

2

यहां लोगों के सुझावों के लिए धन्यवाद, जो शायद प्रासंगिक हैं, लेकिन मेरे विशिष्ट मामले में मदद नहीं की।

यदि आप इसे एक ही समस्या का सामना कर रहे हैं, तो शायद यह max_fetch_depth सुझाव का प्रयास करने लायक है, लेकिन किसी कारण से यह मेरे लिए काम नहीं करता है (मुझे सुझाव क्यों पसंद हैं?)।

इसी प्रकार, यदि आपकी @ वनटॉनी की सूची सूचियों की बजाय सेट है, तो एक उत्सुक fetch या बाएं शामिल हो रही है, जैसा कि अल्बर्ट द्वारा सुझाया गया है, लेकिन स्पष्ट रूप से हाइबरनेट केवल आपको अधिकतम 1 सूची देता है जो उत्सुकता से प्राप्त होता है, यदि आपको उससे अधिक की आवश्यकता है, तो आपके संग्रह सेट होना चाहिए। मैंने कोशिश नहीं की, लेकिन मुझे संदेह है कि इससे समस्या हल हो सकती है।

जब तक कि किसी के पास कोई बेहतर सुझाव न हो, मैं रीफ्रेश कॉलिंग के साथ रहूंगा, जो वास्तव में मेरे आवेदन के लिए शायद अधिक समझ में आता है।

1

यह वास्तव में अजीब है। एक तरह से यह आस-पास काम करने के लिए वस्तु एक छोड़ दिया में शामिल होने-फ़ेच करने के लिए क्वेरी करने के लिए किया जाएगा -> बी> सी> डी जो यदि आपका वैसे भी डी आपत्ति करने के लिए नीचे पार करने के लिए जा रहा भी तेज है। यह ऐसा कुछ होगा।

"from A left join fetch B left join fetch C left join fetch D" 

क्या आपने सी-> डी उत्सुक से संबंध बनाने का भी प्रयास किया है? जिज्ञासु क्या तो क्या होगा ...

+0

धन्यवाद अल्बर्ट, मैंने दोनों सुझावों का प्रयास नहीं किया, इसका कोई फायदा नहीं हुआ :(रिश्तेदार उत्सुकता से कोई प्रभाव नहीं पड़ा, इसलिए मैंने सभी 3 रिश्ते (ए-> बी-> सी-> डी) उत्सुक बनाने की कोशिश की, लेकिन हाइबरनेट ने शिकायत की "एक साथ नहीं हो सकता कई बैग लाएं "। जेपीक्यूएल में बाएं जॉइन जोड़ना एक ही परिणाम था। मुझे कुछ और जगह मिल गई है जो यह सुझाव दे रही है कि ऐसा इसलिए है क्योंकि संग्रह जो मैं उत्सुकता से प्राप्त कर रहा हूं वह सूचियां हैं, और अगर मैं उन्हें सेट करता हूं तो यह काम करेगा, लेकिन मैं अब ऐसा करने के लिए बहुत आलसी हूं, इसलिए मुझे लगता है कि मैं सिर्फ एक ताज़ा कॉल के साथ रखूंगा! – DaveyDaveDave

1

हाइबरनेट डॉक्स कहते हैं कि तुम hibernate.max_fetch_depth संपत्ति के साथ सेट कर सकते हैं। डिफ़ॉल्ट 3 है। आप पेज 47 पर "Hibernate Reference Documentation" में इसे पा सकते हैं।

+0

इसके लिए धन्यवाद - क्या आपको पता है कि hibernate.properties फ़ाइल का उपयोग हाइबरनेट जेपीए द्वारा भी किया जाता है, मुझे नहीं मिल रहा Hibernate दस्तावेज़ों में कहीं भी एक जवाब? मैंने इसे 4 और 0 में बदलने की कोशिश की है, और ऐसा कोई प्रभाव नहीं पड़ता है ... – DaveyDaveDave

+0

ठीक है, उपरोक्त को अनदेखा करें, ऐसा लगता है कि max_fetch_depth को सेट करके 0 टूट गया है मेरे ऐप के अन्य हिस्सों :) इसे एक उच्च संख्या में सेट करना हालांकि (मैंने 4 और 10 की कोशिश की है), ऐसा कोई प्रभाव नहीं प्रतीत होता है; मुझे लगता है क्योंकि यह सिर्फ अधिकतम है, और कुछ और हाइबरनेट को 3 स्तरों पर रोकने के लिए राजी कर रहा है ...? – DaveyDaveDave

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