NHibernate对象引用未保存的瞬态实例,在刷新之前保存瞬态实例

时间:2013-11-17 05:15:47

标签: c# nhibernate

我正在尝试保存一个内部有许多引用元素的复杂对象,并且它在大多数时间都能正常工作 但是在某些情况下,我们会得到以下异常,

  

对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例,或者将属性的级联操作设置为使其自动保存的事件。类型:Namespace.Core.Client.ClientDetails,Entity:Namespace.Core.Client.ClientDetails

问题是,我的复杂对象中有大约12个ClientDetails元素,我们正试图保存。有没有办法识别哪个对象实例导致了这个问题? 通过NHibernate日志记录或其他方式? 我的代码示例用于保存,如下所示,

_repository.Save<SuperParent>(obj);
_repository.Flush();

请注意,当我将Nhibernate show_sql设置为true时,我能够看到正确生成的所有查询,但是当调用flush时,会抛出异常。

请帮助解决问题。

4 个答案:

答案 0 :(得分:14)

该异常表示此对象引用了未保存的ClientDetails实例。您必须在保存父

之前手动保存
session.Save(Parent.SomeDetail);

或在父映射中的引用映射上设置Cascade.SaveOrUpdate

答案 1 :(得分:2)

如果你仔细阅读:

  

...在刷新之前的瞬态实例或为该属性设置级联操作会使其自动保存

所以,也许你可以将Cascade添加到Reference中,如下所示:

References(x => x.ClientDetails).Cascade.All().Column("ClientDetailsId")
                  .Not.Nullable();  //Or nullable, this depends on your schedule

答案 2 :(得分:1)

将映射编辑为级联所有更改。如果您的客户端类包含许多ClientDetails,则XML映射将如下所示

在Client.hbm.xml文件中,您应该具有:

<set name = "ClientDetails" table = "`ClientDetail`" cascade = "all-delete-orphan" inverse="true"> 
         <key column = "ClientId"/> 
         <one-to-many class = "ClientDetail"/> 
</set>

在ClientDetail.hbm.xml文件中,您应该具有:

<many-to-one name = "Client" class = "Client" column = "ClientId " />

答案 3 :(得分:0)

当您有一个复杂的对象,其中包括作为参考数据的子对象时(请考虑ClientType类),也会发生此错误。 如果子级的映射文件中有一个version元素映射到数据库中的int列,则现有行的版本号永远不应设置为0。Nhibernate会将其解释为要在级联更新中插入的对象,并且尝试插入已存在的行时失败。