2

我试图在会话中获取具有惰性属性的对象,并尝试在另一个会话中更新它。但它没有这样做,并出现错误:SecUserProxy 没有持久性(实际类是 SecUser)

我正在使用 NHibernate 3.4。当我用谷歌搜索时,我知道它是一个已修复的错误。

我还看到了这篇文章,其中说如果您的代理对象实现了 INhibernateProxy,您可以使用 NHibernate 取消代理该对象。由于 NHibernate 不再支持可插入代理工厂(如 Castle、LinFu 等),它使用内部代理工厂,我假设内部代理工厂可能是 INhibernateProxy

所以我在新会话中执行了以下操作,我想将我的对象更新为:

 object unprox_obj = Session
     .GetSessionImplementation()
     .PersistenceContext.Unproxy(secUserobj);

期望获得相同的对象,但具有真实类型,即 SecUser,以便它可以更新而不会出现任何错误。但它仍然返回一个代理对象。

我无法理解发生了什么?

更新: 我刚刚意识到'secUserobj'不是INhibernateProxy。那么我怎样才能让它 INhibernateProxy 以便在另一个会话中更新我的对象呢?

 if (secUserobj is INHibernateProxy)
 {
     unprox_obj = Session
        .GetSessionImplementation()
        .PersistenceContext.Unproxy(secUserobj);
 }
4

1 回答 1

2

分离的对象(在一个会话中加载,并作为参考保存)可以重新附加。我们可以使用session.Merge()session.Lock()

9.4.2. 更新分离的对象

许多应用程序需要在一个事务中检索一个对象,将其发送到 UI 层进行操作,然后将更改保存在一个新事务中......

...

...最后一种情况可以通过使用来避免Merge(Object o)。此方法将给定对象的状态复制到具有相同标识符的持久对象上。如果当前没有与会话关联的持久实例,它将被加载。该方法返回持久实例。如果给定的实例未保存或在数据库中不存在,NHibernate 将保存它并将其作为新的持久实例返回。否则,给定实例不会与会话关联。在大多数具有分离对象的应用程序中,您需要方法SaveOrUpdate()Merge().

19.1.4. 初始化集合和代理

...
您还可以在访问未初始化的集合(或其他代理)时Merge()或之前将先前加载的对象附加到新的 ISession。不,NHibernate 不会,当然也不应该自动执行此操作,因为它会引入临时事务语义! ...Lock()

因此,我们可以将分离的引用传递给.Merge(),然后使用返回的(全新的)对象引用:

MyEntity reAttached = session.Merge<MyEntity>(detached);

请注意,这应该在接触任何分离的集合之前完成(如上所述)。

于 2015-05-21T11:34:08.570 回答