मैं यहां एक नुकसान में हूं, और शायद यह कुछ स्पष्ट है क्योंकि मेरी हाइबरनेट विशेषज्ञता अन्य क्षेत्रों की तुलना में कमजोर है।हाइबरनेट मौजूदा डेटा माइग्रेट करने के लिए एम्बेड करने योग्य वर्ग को स्वैप आउट करें
विरासत कोड में एक हाइबरनेट @Entity
कक्षा Foo
है।
private OldBar bar = new OldBar();
OldBar
एक @Embeddable
वर्ग एकल स्तंभ, foobar
का उपयोग करता है:
@Embeddable
public class OldBar {
private String fooBar;
@Column(length = 10, nullable = false)
private String getFooBar() {
return fooBar;
}
@SuppressWarnings("unused")
private void setFooBar(String fooBar) {
this.fooBar = fooBar;
}
}
मूल समस्या यह है कि मैं OldBar.fooBar
साथ कुछ करने की जरूरत है, लेकिन इसके गुणों में से एक यह है मूल डिजाइन में सीमाएं थीं और मुझे यह क्षेत्र निजी था, मुझे इसे सबक्लासिंग से रोक रहा था, इसलिए मुझे एक और अन्य वर्ग, NewBar
बनाना था, दूसरे को बदलने और निजी क्षेत्र तक पहुंच प्राप्त करना था। मैंने सोचा था कि के बाद से NewBar
भी Embeddable
है और एक ही @Column
पद है, मैं सिर्फ बाहर क्षेत्र वर्ग Foo
में स्वैप कर सकते हैं:
private NewBar bar = new NewBar();
मैं क्योंकि मैं foobar
कॉलम में मौजूदा डेटा है यह करने के लिए चाहते थे, और मैं OldBar
के बजाय NewBar
के साथ पारदर्शी रूप से इस डेटा का उपयोग करना चाहता था।
ट्रेस लॉग के माध्यम से मैंने देखा है कि Foo()
NewBar()
के डिफ़ॉल्ट संस्करण के साथ बनाया गया है, जैसा कि कोई उम्मीद करेगा, जब निर्माता को बुलाया जाता है। हालांकि, समय कोड Foo.getBar()
पर कॉल करता है, किसी कारण से bar
null
है! मुझे लगता है कि हाइबरनेट इसे किसी कारण से null
पर सेट कर रहा है --- लेकिन foobar
कॉलम से डेटा पढ़ने और NewBar
का उदाहरण क्यों नहीं बना रहा है? जब मैं के स्थान पर OldBar
डालता हूं तो यह फिर से काम क्यों करता है? निश्चित रूप से डेटाबेस में कुछ भी नहीं है जो कहता है कि @Embeddable
कक्षाओं में से कौन सा कॉलम पर मैप किया गया है, है ना?
अद्यतन: यह अजनबी और अजनबी हो जाता है। कभी-कभी मैं रात भर कोड दूंगा, और अगले दिन यह काम करता है! या अगले दिन यह काम नहीं करता है! अभी यह काम नहीं कर रहा है (यानी, foobar
संपत्ति डेटाबेस में मान के बजाय null
पर सेट की गई थी), इसलिए मैंने ExactCopyOfOldBar
कक्षा बनाई और इसे OldBar
के स्थान पर रखा। यह ठीक काम किया! इसलिए मैं NewBar
पर वापस स्विच करता हूं --- केवल मेरे अस्थायी परिवर्तनों को पूर्ववत करता हूं। यह अभी भी काम करता था, जब यह पहले नहीं था! क्या वहां कुछ प्रकार का कैश है जहां हाइबरनेट मूल्यों को क्रमबद्ध करता है और उन्हें डेटाबेस से नहीं मिलता है? यह बहुत अजीब है।
अद्यतन: अब मुझे काम करने के लिए NewBar
नहीं मिल सकता है। मैं OtherBar
बना देता हूं, जो मूल रूप से NewBar
के समान है, सिवाय इसके कि इसका एक अलग नाम है, और मैं इसे प्लग करता हूं और यह काम करता है, एम्बेडेड स्ट्रिंग को सही ढंग से पढ़ता है। मैं NewBar
पर वापस स्विच करता हूं, और मुझे null
फिर से मिलता है। क्या हो रहा है?
ध्यान दें कि Foo
net.databinder.auth.hib.AuthDataApplication.getUser(String username)
के माध्यम से लोड किया जा रहा है, जो काफी सरल है:
return (DataUser) Databinder.getHibernateSession().createCriteria(getUserClass())
.add(Restrictions.eq("username", username)).uniqueResult();
मैं Foo
(उपयोगकर्ता) की मेज, सही डेटा के साथ एक ही पंक्ति है कि अधिक सत्यापित करने के बाद बार-बार और सबसे महत्वपूर्ण बात यह है कि foobar
फ़ील्ड में डेटा है। Hibernate मुझे Foo
पर null
foobar
फ़ील्ड के साथ क्यों लौटा रहा है? NewBar
से OtherBar
पर स्विच करने से यह फिर से काम करना शुरू कर देता है? यह पूरे दिन क्यों काम करता है और फिर रात भर छोड़ने के बाद काम करना बंद कर देता है?
मुझे लगता है कि यह सच है, लेकिन आपने यह नहीं कहा: क्या 'Foo.bar' '@ एम्बेडेड' के रूप में चिह्नित है? –
@ टिम पोटे: असल में, आश्चर्यजनक रूप से पर्याप्त, मूल (कामकाजी) विरासत कोड में, यह _not_ को '@ एम्बेडेड' के रूप में चिह्नित किया गया था। जब मैंने 'ओल्डबार' को 'न्यूबार' में बदल दिया, तो मैंने इसे '@ एम्बेडेड' के साथ और बिना कोशिश की, और इससे कोई फर्क नहीं पड़ता। –
@ टिम पोटे: मैंने हाइबरनेट [दस्तावेज़ीकरण] (http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/) से सीखा है कि "... यदि संपत्ति का प्रकार @Embeddable के रूप में एनोटेटेड है, इसे @Embedded के रूप में मैप किया गया है, "इसलिए तकनीकी रूप से' @ एम्बेडेड' भाग वैकल्पिक है। –