NHibernate:更改父级 - "deleted object would be re-saved by cascade"



正如标题所说,基本上我想做的是改变孩子的父母。但是当我尝试这样做时,我得到异常"对象删除异常:删除的对象将被级联重新保存(从关联中删除已删除的对象)"。

我已经在谷歌上搜索了几个小时,但我找到的解决方案都不适合我!!

这些是我参与的课程:

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>

这是我尝试将孩子重新分配给另一个父母的代码段:

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

但是,session.Flush()抛出上面的异常。我猜问题在于,既然孩子换了父母,因为级联,NHibernate将不得不消灭孩子,但后来它又被重新分配给了父级,所以,再次因为级联,它将不得不重新拯救孩子。

我已经尝试更改映射,并从前父级的集合中删除 Child(在我将其分配给另一个父级之前或之后),但这些都不起作用......

任何帮助将不胜感激!!

谢谢!!

我看到了你的免责声明:...我已经在谷歌上搜索了几个小时,但我找到的解决方案都不适合我!!

但总的来说,上面的例子根本无法(重新)产生ObjectDeletedException

在 nhibernate 中甚至还有一个内置测试,它检查:

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删除的对象将通过级联重新保存

这里还有一些讨论和更多提示

  • NHibernate:删除的对象将通过级联重新保存。替换对象并删除旧对象

ObjectDeletedException("删除的对象将被重新保存...")几乎总是意味着:某个对象被删除了。即存储在当前session中的信息。但是仍然有一些集合引用它...

不知何故,我无法访问我提出问题的帐户。

事实证明,我们不会在物理上擦除数据,只是在逻辑上,因此将级联更改为"保存-更新"解决了这个问题。

这个链接非常清楚地解释了NHibernate中重新设置父级的问题:

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

我知道

已经有一段时间了,我不知道你是否还需要这个,但我最近遇到了这个问题,这里有一个对我有用的代码片段:

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

基本上,这会删除旧子项,并将具有新 ID 和相同属性的全新子项添加到另一个父项。 这样,您就不必创建子对象的深层副本来将其添加到新的父对象。 它所做的是解除子项与其旧父项的关联,将其删除(从会话中删除),逐出它(强制 nhibernate 忘记对象的存在),重置 ID(假设您使用的是 sql 种子身份列),重新设置其父级,然后将其添加到新父级的集合中。

使用这种策略,我仍然能够在父映射上保留"级联所有删除孤立",而不必使关系"反向"。 希望这对任何遇到这个问题的人都有帮助,这可能是一个真正的痛苦......

相关内容

  • 没有找到相关文章

最新更新