2009-05-31 19 views
6

Tôi đã theo mô hình:Xóa throws "đối tượng bị xóa sẽ được lưu lại bởi cascade"

<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> 

Không có thuộc tính trỏ đến PersonEventRegistration hoặc trong Person hay trong tổ chức sự kiện.

Khi tôi cố gắng xóa một mục từ PersonEventRegistration, tôi nhận được lỗi sau:

"deleted object would be re-saved by cascade" 

Vấn đề là, tôi không lưu trữ đối tượng này trong bất kỳ bộ sưu tập khác - mã xóa trông như thế này:

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; 
} 

Tôi đang làm gì sai ở đây?

Trả lời

3

Theo như tôi biết, cascade="all-delete-orphan" thuộc về yếu tố bản đồ thu thập, không phải là many-to-one. Bạn đã không hiển thị hai phần khác của bản đồ của bạn vì vậy tôi không thể nói chắc chắn nhưng điều này là có thể (có thể) vấn đề.

Tôi nghĩ Person nên giống như thế:

<!-- 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" ? --> /> 

Trên thực tế, ở trên có thể là thác mâu thuẫn (mà có thể là những gì bạn có). Vì vậy, thực sự, câu trả lời của tôi là hai điều:

  1. cascade="all-delete-orphan" không có ý nghĩa trên many-to-one.
  2. Hãy chắc chắn rằng bạn đã thực sự suy nghĩ về cách bạn đang làm việc với các thực thể của bạn và làm thế nào họ nên cascade hoạt động của họ.
+0

tôi đã không nhận thấy bài đăng đó không chứa tất cả định dạng ... anyway - ánh xạ Sự kiện và Người không chứa bất kỳ thông tin nào về PersonEventRegistration. lớp này được sử dụng để hỗ trợ ánh xạ nhiều đối tượng + một số thuộc tính phụ (tôi không tìm thấy bất kỳ ví dụ nào mà nhibernate sẽ hỗ trợ kịch bản như vậy). tôi sẽ thử cascade = "delete". – Greg

+2

Các đề xuất của bạn được phát hiện tại chỗ. Nó không chỉ là "tất cả-xóa-mồ côi" không có ý nghĩa ". Cascading một xóa từ một đứa trẻ lên đến một phụ huynh thường là _evil_. Đó là những gì 'all' và' all-delete-orphan' sẽ thực hiện trên 'nhiều-một-một'. Việc xóa 'PersonEventRegistration' với các thác đó sẽ khiến NHibernate cố gắng xóa' Person' và 'Event', điều này chắc chắn không phải là những gì Greg dự định. Và đó là lý do tại sao xóa không thành công - vì Người và Sự kiện vẫn được tham chiếu ở nơi khác, vì vậy NHibernate không thể xóa chúng. –

+0

... do đó, thác chính xác cho 'nhiều-một-một' thường là' lưu-cập nhật'. –

1

Hãy thử de-tham khảo Người và tổ chức sự kiện trong xóa:

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; 
    } 

Ngoài ra, tôi đã không biết rằng bạn có thể thêm một hạn chế về một đối tượng, tôi sẽ có văn bản này sử dụng bí danh và ID .

  .Add(Restrictions.Eq("Person", person)) 
      .Add(Restrictions.Eq("Event", entry)) 
Các vấn đề liên quan