2010-01-16 14 views
13

मैं इकाई वर्ग के साथ एक बहुत ही अजीब व्यवहार देख रहा हूं और जेपीए (हाइबरनेट इकाई प्रबंधक 3.3.1.ga) के साथ इस वर्ग की एक वस्तु लोड कर रहा हूं। कक्षा में एक (एम्बेडेड) फ़ील्ड है, जिसे घोषणा में शुरू किया गया है। क्षेत्र का सेटटर एक शून्य जांच लागू करता है (यानी एक शून्य मान सेट होने पर अपवाद फेंक देगा)।अजीब जेपीए व्यवहार, प्रारंभिक फ़ील्ड शून्य

... 
@Entity 
public class Participant extends BaseEntity implements Comparable<Participant> { 
    ... 
    @Embedded 
private AmsData amsData = new AmsData(); 

public void setAmsData(AmsData amsData) { 
    Checks.verifyArgNotNull(amsData, "amsdata"); 
    this.amsData = amsData; 
} 
    ... 
} 

जब मैं जेपीए के साथ इस वस्तु मिलता है, फ़ील्ड रिक्त है, अगर वहाँ एम्बेडेड ऑब्जेक्ट में निर्दिष्ट क्षेत्रों के लिए DB में कोई डाटा नहीं है।

... 
public class ParticipantJpaDao implements ParticipantDao { 
@PersistenceContext 
private EntityManager em; 

@Override 
public Participant getParticipant(Long id) { 
    return em.find(Participant.class, id); 
} 
    ... 
} 

मैं मैदान पर एक watchpoint साथ प्रक्रिया डिबग (को रोकने चाहिए जब क्षेत्र पहुँचा या संशोधित किया गया है), और मैं एक संशोधन जब क्षेत्र आरंभ नहीं हो जाता देखते हैं, लेकिन जब मैं खोजने के कॉल से परिणाम प्राप्त , क्षेत्र शून्य है।

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

+0

इस हो सकता है? –

+0

मैं आलसी लोडिंग का उपयोग करता हूं, लेकिन यह एक एम्बेडेड फ़ील्ड है, इसलिए उसी तालिका में संग्रहीत किया जाता है। क्या उत्सुकता से इसे लाने के लिए टिप्पणी करने की संभावना है? – Dominik

+0

संबंधित हाइबरनेट समस्या (हटाए गए उत्तर से लिया गया): [एचएचएच -7610: सभी कॉलम न्यूल होने पर @Embedded फ़ील्ड को सेट करने के लिए विकल्प] (https://hibernate.atlassian.net/browse/HHH-7610) – sleske

उत्तर

16

जेपीए विनिर्देश स्पष्ट रूप से यह नहीं कहता कि कॉलम के एक सेट को कैसे एम्बेड किया जा सकता है जो एक एम्बेडेबल ऑब्जेक्ट का प्रतिनिधित्व करता है जो सभी खाली हैं। यह एक शून्य संदर्भ, या सभी शून्य क्षेत्रों के साथ एक वस्तु उदाहरण संकेत कर सकता है। हाइबरनेट इस मामले में एक शून्य संदर्भ चुनता है, हालांकि अन्य जेपीए कार्यान्वयन बाद में उठा सकते हैं।

आपके सेटर को कभी भी क्यों नहीं कहा जाता है क्योंकि हाइबरनेट आपके द्वारा लागू किए गए सेटटर को छोड़कर प्रतिबिंब के माध्यम से आपके क्षेत्र तक पहुंच रहा है। यह ऐसा इसलिए कर रहा है क्योंकि आप संपत्ति-आधारित पहुंच के बजाय फ़ील्ड-आधारित पहुंच का उपयोग करते हैं।

चाड का उत्तर उस कार्यक्षमता को प्रदान करेगा जो आप खोज रहे हैं, लेकिन वहां एक चेतावनी है (नीचे देखें)।

"... एक इकाई की लगातार राज्य हठ प्रदाता क्रम द्वारा पहुँचा है [1] या तो के माध्यम से JavaBeans शैली संपत्ति accessors या उदाहरण चर के माध्यम से । एक एकल एक्सेस प्रकार (क्षेत्र या संपत्ति पहुँच) एक इकाई पदानुक्रम पर लागू होता है। जब एनोटेशन उपयोग किया जाता है, की नियुक्ति या तो लगातार खेतों या संस्था वर्ग की लगातार गुणों पर मानचित्रण एनोटेशन एक्सेस प्रकार या तो field- ओ होने के रूप में निर्दिष्ट करता है आर संपत्ति आधारित क्रमशः पहुँच ... "[EJB3 हठ कल्पना]

तो एनोटेशन field- के बजाय सेटर, आप जेपीए कह रहे हैं कि आप संपत्ति आधारित पहुंच का इस्तेमाल किया करना चाहते करने के लिए नीचे ले जाकर

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

+0

लेकिन क्यों होगा यह मैदान को शून्य करने के लिए सेट? – Dominik

+0

मैंने यह बताने के लिए जवाब अपडेट किया कि फ़ील्ड शून्य क्यों हो सकता है। सबसे आम कारण यह है कि आपके पास अपने डेटाबेस में रिकॉर्ड हैं जो आपके ** amsData ** फ़ील्ड को जोड़ने का अनुमान लगाते हैं। – rcampbell

+0

मैंने अभी एक नई इकाई को नल (लेकिन खाली) एएमएसडेटा ऑब्जेक्ट के साथ संग्रहीत किया है और मुझे एक ही परिणाम मिल गया है। और हां, एएमएसडेटा वर्ग को एम्बेड करने योग्य एनोटेटेड है। – Dominik

1

अच्छा, यह संभव है कि दृश्यों के पीछे आपकी वस्तु दो बार बनाई जा सके। जेपीए कार्यान्वयन आमतौर पर उन क्षेत्रों को सीधे सेट करेगा।

मुझे लगता है कि अगर आप उन्हें इस्तेमाल करना चाहते हैं तो आपको गेटर्स और सेटर्स पर एनोटेशन डालना होगा। , अगर एक एम्बेडेड वस्तु के सभी डाटा शून्य है (DB में)

Empty constructors and setters on JPA Entites

+0

एम्बेडेड ऑब्जेक्ट में केवल कॉलम और कोई एसोसिएशन नहीं है, जिसे उत्सुकता से लाया जा सकता है। – Dominik

3

जवाब है (धन्यवाद rcampell के लिए), एम्बेडेड वस्तु भी अशक्त हो जाएगा, हालांकि जब यह आरंभ नहीं हो जाता: इस उत्तर देखें घोषणा में। ऐसा लगता है कि ऑब्जेक्ट मैन्युअल रूप से सेट करना एकमात्र समाधान है।

@Override 
public Participant getParticipant(Long id) { 
    Participant participant = em.find(Participant.class, id); 
    if(participant != null && participant.getAmsData() == null) 
    { 
     participant.setAmsData(new AmsData()); 
    } 
    return participant; 
} 
अपने हठ इंजन आलसी लोड हो रहा है संघों के कारण

फिर भी मेरे लिए अजीब लगता है ...

+0

कुछ हफ्ते पहले भी यही समस्या थी। वह चाल करेगा। +1 – whiskeysierra

+0

यह समाधान डेटाबेस सर्वर पर SQL अद्यतन निर्देश को ट्रिगर करता है, चुड़ैल धागे और प्रदर्शन समस्याओं के बीच समेकन जैसी समस्याएं लाता है। –

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