2009-06-11 16 views
5

मुझे किसी SQL सर्वर 2005 डेटाबेस में किसी इकाई को सहेजने में समस्या आ रही है। मैं अपनी दृढ़ता परत के लिए NHibernate 2.0.0.3002 का उपयोग कर रहा हूं। मैपिंग सामान्य है, एक पूर्णांक आईडी के साथ,एनआईबीबर्नेट "शून्य पहचानकर्ता" एक इकाई डालने के बाद अपवाद

<id name="Id" unsaved-value="0"> 
    <column name="Id"/> 
    <generator class="identity" /> 
</id> 

मैंने शेष को ब्रेवटी के लिए छोड़ दिया है। के रूप में

public void Save(T toSave) 
{ 
    Save(new T[] { toSave }); 
} 

public void Save(IEnumerable<T> toSave) 
{ 
    using (ISession session = SessionFactory.OpenSession()) 
    { 
     foreach (T item in toSave) 
     { 
      session.SaveOrUpdate(item); 
     } 
     session.Flush(); 
    } 
} 

जब सत्र पर SaveOrUpdate बुला, एक अपवाद "शून्य पहचानकर्ता" के एक संदेश के साथ फेंक दिया जाता है इस प्रकार आवेदन एक सामान्य बचाने विधि के साथ भंडार वर्ग का उपयोग कर रहा है। जब मैं डेटाबेस की जांच करता हूं तो पंक्ति सभी सही मानों के साथ डाली गई है, इसलिए मुझे लगता है कि समस्या तब होती है जब NHibernate इकाई की आईडी प्रॉपर्टी को @@ पहचान द्वारा लौटाए गए मान के साथ सेट करने का प्रयास करता है। मैं एसक्यूएल प्रोफाइलर के माध्यम से देख सकता हूं कि @@ पहचान को बुलाया जा रहा है, इसलिए मुझे समझ में नहीं आता कि अपवाद क्यों फेंक दिया गया है।

क्या किसी और को यह समस्या है?

+0

क्या आप उस कोड को दिखा सकते हैं जो वास्तविक बचत/अद्यतन करता है और जब आप उस आईडी का उपयोग करने का प्रयास करते हैं? –

+0

मैंने अनुरोध के रूप में कोड जोड़ा है। – gilles27

+0

एनएचबीरनेट का कौन सा संस्करण आप बीटीडब्ल्यू चला रहे हैं? –

उत्तर

8

दोनों को बचाने और लेन-देन में भी हो सकता है और लेन-देन अंत में प्रतिबद्ध होना चाहिए हटाएँ।

तो जैसे:

public void Save(IEnumerable<T> toSave) 
{ 
    using (ISession session = SessionFactory.OpenSession()) 
    { 
     ITransaction transaction = Session.BeginTransaction(); 

     foreach (T item in toSave) 
     { 
      session.SaveOrUpdate(item); 
     } 

     transaction.Commit();   
     session.Flush(); 
    } 
} 

कृपया ध्यान दें: आप रैप करने के लिए है कि एक का उपयोग करने में और ठीक से रोलबैक चाहता हूँ ... भी है, जहां आप खोल रहे हैं और लेन-देन करने की प्लेसमेंट के आधार बात करेंगे आपका परिदृश्य जब आप पूरा कर लेंगे तो आपको लेनदेन को बंद करना चाहिए ...

इसके अलावा, क्या आप अपवाद कहां हो रहे हैं, इस पर विस्तृत जानकारी दे सकते हैं? ऐसा लगता है जैसे आप माता-पिता को बचा रहे हैं और फिर बच्चा फेंक रहा है क्योंकि माता-पिता की आईडी शून्य है? या, क्या यह वास्तव में माता-पिता को बचाने पर फेंक रहा है?

+0

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

+0

वास्तव में कोई अच्छा तरीका नहीं है, imho। यह सब आपके विशिष्ट डिजाइन पर निर्भर करता है। आम तौर पर, मेरे पास कुल जड़ें हैं जो बच्चों को कैस्केड निर्दिष्ट करती हैं। मैं फिर लेनदेन में कुल रूट स्तर पर बचत लपेटता हूं। उदाहरण के लिए। उत्तर में टिप्पणियां हैं इसलिए मैं एक जवाब दूंगा। जोड़ें टिप्पणी (टिप्पणी); answerRepository.Save (उत्तर)। लेनदेन में सहेजने के लिए मेरी नई पसंदीदा विधि एफएनएच (पुराने) स्रोत से आता है .... थोड़ा सा पोस्ट करेगा। – Ben

+0

' सार्वजनिक शून्य सहेजें (टी इकाई) { भीतर लेनदेन (() => सत्र .aveOrUpdate (इकाई)); } निजी शून्य अंदर लेनदेन (क्रिया क्रिया) { आईट्रांसक्शन लेनदेन = सत्र। बेजिन ट्रान्सएक्शन(); { कार्रवाई(); लेनदेन। कॉमिट(); } पकड़ (अपवाद) { लेनदेन। रोलबैक(); फेंक; } अंत में { लेनदेन। उद्देश्य(); } } ' – Ben

-2

मैं जनरेटर वर्ग = "identitiy" के बजाय />

कोशिश जनरेटर वर्ग = "guid.comp"

+0

मुझे लगता है कि आप guid.comb का मतलब है, guid.comp नहीं। किसी भी मामले में जो काम नहीं करेगा क्योंकि मैं एक पूर्णांक कुंजी के साथ काम कर रहा हूं, GUID कुंजी नहीं। – gilles27

+1

हालांकि यह इस विशेष मामले में काम नहीं करता है, यह मेरे लिए काम करता है। कोई बुरा जवाब नहीं – Batman

0

पहचान सुंदर NHibernate डेवलपर्स द्वारा हतोत्साहित किया जाता है लगता है .. मुख्य मुद्दा हम में भाग है जब तक आप फ्लश नहीं करते हैं, आपको एक आईडी नहीं मिलता है। आपके इंट केस में हायलो एक अच्छा प्रतिस्थापन होगा।

कहा जा रहा है मुझे लगता है कि आप वास्तव में ऐसा करना चाहते हैं ...

<id name="Id" column="Id" unsaved-value="0"> 
    <generator class="identity"/> 
</id> 
+0

मैंने यहां दिखाए गए एक्सएमएल का उपयोग करने का प्रयास किया है लेकिन समस्या बनी हुई है। मुझे लगता है कि एक्सएमएल मेरे ऊपर के बराबर है, बस थोड़ा और अधिक है। – gilles27

1

यह शायद मददगार log4net कॉन्फ़िगर करने के लिए इतना है कि आप लॉग इन करें और कार्रवाई है कि NHibernate कर रहा है देख सकते हैं ...

मैं एक बार के साथ-साथ Access का उपयोग NHibernate के साथ एक समस्या थी, और द्वारा इसे हल करने में सक्षम था लॉगिंग सेट अप करना ताकि मैं समस्या के कारण को ठीक से इंगित कर सकूं।

मुझे प्राप्त त्रुटि संदेश, आपके से अलग था, लेकिन this वह आलेख है जहां मैं वर्णन करता हूं कि मैंने अपनी समस्या का समाधान कैसे किया। शायद यह आपके लिए सहायक हो सकता है। :)

+0

मैंने एनएचबीरनेट द्वारा निष्पादित एसक्यूएल का निरीक्षण करने के लिए प्रोफाइलर का उपयोग किया है और यह सब सही दिखाई देता है। यह रिकॉर्ड की नई आईडी पुनर्प्राप्त करने के लिए @@ पहचान भी कॉल करता है, लेकिन इसके बाद अपवाद फेंक दिया जाता है। बस स्पष्ट होने के लिए, मैं SQL सर्वर का उपयोग कर रहा हूं, एक्सेस नहीं। – gilles27

+0

मैंने सोचा था कि आपने एक बार अपने टीएस में कहा था कि आप एक्सेस का उपयोग कर रहे हैं? वैसे भी, आपकी मदद करने की कोशिश करने वाले सभी लोगों को डाउनग्रेड करने के लिए अच्छा चैप, लेकिन सही समाधान प्रदान नहीं किया ... –

+0

अगर मैं आपको अपने उत्तर को डाउनग्रेड करके नाराज करता हूं तो मैं क्षमा चाहता हूं। हालांकि मैं इस साइट की भावना में विश्वास करता हूं कि गलत या भ्रामक उत्तरों को वोट दिया जाना चाहिए ताकि सर्वोत्तम सामग्री शीर्ष पर हो। अपना उत्तर नीचे वोट देना आपके लिए महत्वपूर्ण नहीं है या ब्लॉग पोस्ट जो आपने लिंक किया है। मदद करने की कोशिश करने के लिए धन्यवाद। – gilles27

0

मुझे यह त्रुटि भी मिली और इसका समाधान लेनदेन में लपेटना था क्योंकि बेन ने उल्लेख किया था। हालांकि, मैं काम नहीं करने के लिए बेन और न ही गिल्स 27 कोड प्राप्त करने में सक्षम था - शायद क्योंकि मैं जेनेरिक और एनएचबीरनेट के लिए नया हूं। मैंने थोड़ा अलग कार्यान्वयन बनाया जो काम करता है (फ्लुएंट एनएचबेर्नेट v1 का उपयोग करके।3):

 public static ISession LocalDbSession = null; 

    public static void Save<T>(T toSave) 
    { 
     using (var transaction = LocalDbSession.BeginTransaction()) 
     { 
      LocalDbSession.Save(toSave); 
      transaction.Commit(); 
      LocalDbSession.Flush(); 
     } 
    } 

    public static void Save<T>(IEnumerable<T> toSave) 
    { 
     using (var transaction = LocalDbSession.BeginTransaction()) 
     { 
      foreach (T item in toSave) 
      { 
       LocalDbSession.Save(item); 
      } 

      transaction.Commit(); 
      LocalDbSession.Flush(); 
     } 
    } 
संबंधित मुद्दे