2009-05-31 14 views
6

मैं मॉडल का अनुसरण किया है "नष्ट कर दिया वस्तु झरना द्वारा फिर से बचाया जाएगा" थ्रो:हटाएं

<class name="Person" table="Person" optimistic-lock="version"> 
    <id name="Id" type="Int32" unsaved-value="0"> 
    <generator class="native" /> 
    </id> 
    <!-- plus some properties here --> 
</class> 

<class name="Event" table="Event" optimistic-lock="version"> 
    <id name="Id" type="Int32" unsaved-value="0"> 
    <generator class="native" /> 
    </id> 
    <!-- plus some properties here --> 
</class> 

<class name="PersonEventRegistration" table="PersonEventRegistration" optimistic-lock="version"> 
    <id name="Id" type="Int32" unsaved-value="0"> 
    <generator class="native" /> 
    </id> 
    <property name="IsComplete" type="Boolean" not-null="true" /> 
    <property name="RegistrationDate" type="DateTime" not-null="true" /> 
    <many-to-one name="Person" class="Person" column="PersonId" foreign-key="FK_PersonEvent_PersonId" cascade="all-delete-orphan" /> 
    <many-to-one name="Event" class="Event" column="EventId" foreign-key="FK_PersonEvent_EventId" cascade="all-delete-orphan" /> 
</class> 

कोई गुण या तो व्यक्ति में है और न ही घटना में PersonEventRegistration की ओर इशारा करते हैं।

जब मैं PersonEventRegistration से किसी प्रविष्टि को हटाने का प्रयास, मैं निम्नलिखित त्रुटि मिलती है:

"deleted object would be re-saved by cascade" 

समस्या है, मैं किसी अन्य संग्रह में इस वस्तु की दुकान नहीं है - हटाने कोड इस तरह दिखता है:

public bool UnregisterFromEvent(Person person, Event entry) 
{ 
    var registrationEntry = this.session 
     .CreateCriteria<PersonEventRegistration>() 
     .Add(Restrictions.Eq("Person", person)) 
     .Add(Restrictions.Eq("Event", entry)) 
     .Add(Restrictions.Eq("IsComplete", false)) 
     .UniqueResult<PersonEventRegistration>(); 

    bool result = false; 
    if (null != registrationEntry) 
    { 
     using (ITransaction tx = this.session.BeginTransaction()) 
     { 
      this.session.Delete(registrationEntry); 
      tx.Commit(); 
      result = true; 
     } 
    } 
    return result; 
} 

मैं यहां क्या गलत कर रहा हूं?

उत्तर

3

जहाँ तक मुझे पता है, cascade="all-delete-orphan" संग्रह मैपिंग तत्व पर है, many-to-one नहीं। आपने अपने मैपिंग के अन्य दो हिस्सों को नहीं दिखाया है, इसलिए मैं निश्चित रूप से नहीं कह सकता लेकिन यह समस्या (संभावित) समस्या है।

मुझे लगता है कि Person कुछ ऐसा दिखाई देगा:

<!-- other properties --> 
<set name="Events" inverse="true" cascade="all-delete-orphan"> 
    <key column="Person_id" /> 
    <one-to-many class="PersonEventRegistration" /> 
</set> 

Event:

<!-- similar mapping for Event --> 

PersonEventRegistration: जो हो सकता है

<!-- other properties --> 
<many-to-one name="Person" class="Person" column="PersonId" foreign-key="FK_PersonEvent_PersonId" cascade="delete" <!-- or many ="all" ? --> /> 

वास्तव में, इसके बाद के संस्करण विरोधी cascades हो सकता है (क्या आपके पास)।

  1. cascade="all-delete-orphan"many-to-one पर कोई अर्थ नहीं है: तो सच में, मेरा उत्तर दो बातें है।
  2. सुनिश्चित करें कि आपने वास्तव में सोचा है कि आप अपनी संस्थाओं के साथ कैसे काम कर रहे हैं और उन्हें अपने परिचालनों को कैसे रोकना चाहिए।
+0

मैं उस पोस्ट नोटिस नहीं किया था वैसे भी सभी स्वरूपण ... शामिल नहीं किया - घटना और व्यक्ति मैपिंग PersonEventRegistration के बारे में कोई जानकारी नहीं होती। इस वर्ग का उपयोग कई से अधिक मैपिंग + कुछ अतिरिक्त विशेषताओं का समर्थन करने के लिए किया जाता है (मुझे कोई ऐसा उदाहरण नहीं मिला जहां निबर्ननेट इस तरह के परिदृश्य का समर्थन करेगा)। मैं वैसे भी कैस्केड = "हटाएं" कोशिश करूंगा। – Greg

+2

आपकी सिफारिशें स्पॉट-ऑन हैं। यह सिर्फ "सब-डिलीट-अनाथ" का अर्थ नहीं है "। एक बच्चे से माता-पिता तक एक डिलीट को कैस्केड करना आम तौर पर _evil_ है। यही 'सब' और 'ऑल-डिलीट-अनाथ' 'कई से एक' पर होगा। उन लोगों के साथ 'PersonEventRegistration' को हटाने से NHHernate' व्यक्ति 'और' ईवेंट 'को भी हटाने का प्रयास करेगा, जो निश्चित रूप से ग्रेग का इरादा नहीं है। और यही कारण है कि डिलीट विफल हो जाता है - क्योंकि व्यक्ति और घटना को अभी भी कहीं और संदर्भित किया जाता है, इसलिए NHibernate उन्हें हटा नहीं सकता है। –

+0

... इसलिए 'कई से एक' के लिए सही कैस्केड आमतौर पर 'सेव-अपडेट' होता है। –

1

कोशिश de-संदर्भित हटाने में व्यक्ति और घटना:

public bool UnregisterFromEvent(Person person, Event entry) 
    { 
     var registrationEntry = this.session 
      .CreateCriteria<PersonEventRegistration>() 
      .Add(Restrictions.Eq("Person", person)) 
      .Add(Restrictions.Eq("Event", entry)) 
      .Add(Restrictions.Eq("IsComplete", false)) 
      .UniqueResult<PersonEventRegistration>(); 

     bool result = false; 
     if (null != registrationEntry) 
     { 
      using (ITransaction tx = this.session.BeginTransaction()) 
      { 
       registrationEntry.Person = null; 
       registrationEntry.Event = null; 
       this.session.Delete(registrationEntry); 
       tx.Commit(); 
       result = true; 
      } 
     } 
     return result; 
    } 

इसके अलावा, मुझे पता है आप एक वस्तु पर एक प्रतिबंध जोड़ सकता है कि नहीं था, मैं इस उपनाम और आईडी का उपयोग लिखा है | ।

  .Add(Restrictions.Eq("Person", person)) 
      .Add(Restrictions.Eq("Event", entry)) 
संबंधित मुद्दे