2015-01-23 9 views
2

제목에서 말했듯이, 기본적으로 내가하고 싶은 것은 자식의 부모를 변경하는 것입니다. 하지만 이렇게하려고하면 "ObjectDeletedException : 삭제 된 개체가 연쇄 (삭제 된 개체를 연결에서 제거)로 다시 저장됩니다"예외가 발생합니다.NHibernate : 부모 변경 - "삭제 된 객체는 캐스케이드로 다시 저장됩니다"

나는 지금 몇 시간 씩 인터넷 검색을 해왔지만 찾은 해결책 중 아무 것도 나를 위해 일하지 않았다 !!

내 클래스가 포함됩니다 :

public class Parent: Entity 
{ 
    public virtual IList<Child> Children { get; set; } 
} 

public class Child: Entity 
{ 
    public virtual DateTime? CancellationDate { get; set; } 
} 

클래스 엔티티는 Id 속성을 가지고있는 것입니다.

부모의 매핑 (Parents.hbm.xml)입니다 :

<bag name="Children" cascade="all-delete-orphan" table="Schema.Child" where="CancellationDate is null"> 
    <key column="ParentID"/> 
    <one-to-many class="Namespace.Child"/> 
</bag> 

그리고 이것이 내가 다른 부모에게 아이를 reasign하려고 코드의 조각 :

foreach(Child c in Parent1.Children) 
{ 
    Parent2.Children.Add(c); 
} 

그러나 그런 다음 session.Flush()이 예외를 throw합니다. 그 문제는 자식이 부모를 바꿨 기 때문에, NHibernate가 자식을 제거해야 할 것이기 때문에 그 부모가 바뀌었기 때문이며, 그러나 anothet 부모에게 재 할당되었다. 다시 말하자면, 다시 캐스케이드 때문에, 아이를 구하십시오.

는 이미

어떤 도움 매우 감사하겠습니다 ... (이전 또는 이후에 내가 다른 부모에 할당)하지만 일을 그 아무도 매핑을 변경, 이전 부모의 컬렉션에서 아이를 제거하려 !! !!

감사합니다.

+0

가능한 해결 방법은 parents1에 parent1 하위의 사본을 추가하려고합니다. 알고 있다면, 이것은 parent2와 연관된 db에 (저장 후) 새로운 레코드를 생성하고 parent1 자식들의 행들을 제거 할 것입니다. 아니면 ParentId를 업데이트하고 싶습니까? – ASh

+0

그래, 그 해결책에 대해 생각했지만 새 아이디를 만들 수는 없어. 아이의 ID는 그대로있어 ... 어쨌든! –

+0

도움이 되셨습니까? http://stackoverflow.com/questions/2763985/how-do-i-change-a-childs-parent-in-nhibernate-when-cascade-is-delete-all-orphan – ASh

답변

0

귀하의 면책 조항을 보았습니다 : ... 저는 지금 몇 시간 씩 인터넷 검색을 해왔지만 발견 된 해결책 중 아무 것도 나를 위해 일하지 않았습니다 !!

그러나 일반적으로는 예를 들어 위의 ObjectDeletedException을 생산하는 (재) 할 수 단순히 결코입니다. 이 테스트는 통과

NHibernate.Test.NHSpecificTest.NH1531 SampleTest ReparentingShouldNotFail

[Test] 
public void ReparentingShouldNotFail() 
{ 
    FillDb(); 
    using (ISession session = OpenSession()) 
    { 
     var parent1 = session.Get<Parent>(1); 
     var parent2 = session.Get<Parent>(2); 

     Assert.AreEqual(1, parent1.Children.Count); 
     Assert.AreEqual(0, parent2.Children.Count); 

     Child p1Child = parent1.Children[0]; 

     Assert.IsNotNull(p1Child); 

     parent1.DetachAllChildren(); 
     parent2.AttachNewChild(p1Child); 

     session.Update(parent1); 
     session.Update(parent2); 

     // NHibernate.ObjectDeletedException : 
     // deleted object would be re-saved by cascade 
     // (remove deleted object from associations) 
     // [NHibernate.Test.NHSpecificTest.NH1531.Child#0] 

     session.Flush(); 
    } 
    ... 

: 심지어 있는지 확인 NHibernate에의 테스트, 내장이

.

그래서 문제는 어디에 있습니까? 당신이 보여주지 않은 코드에서 단순히 somwhere. 이러한 문제의 상세한 설명은 여기에서 볼 수 있습니다 : 또한

등을 논의하고 여기에 더 힌트

ObjectDeletedException(" 삭제 된 개체가 다시 저장됩니다 ...")은 거의 항상 다음을 의미합니다 : 일부 객체가 삭제되었습니다. 현재 session에 저장된 정보입니다. 그러나 참조하는 컬렉션이 아직 있습니다 ...

0

어떻게 든 질문을 한 계정에 액세스 할 수 없습니다.

우리가 phisically 그래서 문제를 '저장 업데이트'캐스케이드 해결 변경, 논리적으로 만 데이터를 삭제하지 않는 것이 밝혀

를이 링크는 자 NHibernate에서, 친 매우 명확하게 문제를 설명합니다.

http://osdir.com/ml/nhusers/2009-09/msg00323.html

0

나는 그것 오랜만 당신은 여전히이 필요하면 나도 몰라,하지만 난 최근에이 문제에 달려 여기에 나를 위해 일한 코드 알고 : 기본적으로

parent.Children.Remove(child); 
session.Delete(child); 
session.Evict(child); 
child.ID = 0; 
child.Parent = otherParent; 
otherParent.Children.Add(child); 

,이 삭제 오래된 아이를 추가하고 새로운 ID와 동일한 속성을 가진 새로운 것을 새로운 부모에게 추가합니다. 이렇게하면 하위 개체의 전체 복사본을 만들어 새 부모 개체에 추가 할 필요가 없습니다. 그 일을하는 것은 이전 부모로부터 아이를 분리하고, 그것을 세션에서 삭제하고, 그것을 제거하고 (객체의 존재를 잊어 버리기 위해 nhibernate를 강제 함), ID를 재설정하고 (당신이 SQL 시드 된 아이덴티티 컬럼을 사용한다고 가정), 다시 부모 역할을한다. 새로운 부모의 컬렉션에 추가합니다.

이 전략을 사용하면 부모 매핑에서 "계단식 모두 삭제"고아를 유지하면서 관계를 "역으로"만들지 않아도됩니다. 이 문제를 해결하는 데 도움이 되었기를 바랍니다.