小编Buf*_*nOK的帖子

在NHibernate StaleObjectStateException之后如何优雅地合并对象图?

我们正在尝试在抛出StaleObjectStateException之后组合对象以保存合并副本.

这是我们的环境状况:

  • 项目清单
  • 多用户系统
  • WPF桌面应用程序,SQL Server 2008数据库
  • NHibernate 3.1.0.4000,FluentNHibernate 1.2.0.712
  • 全球,长期运行的NHibernate会议[目前.我们了解会话演示者是推荐的模式,但目前没有时间在我们的项目进度表中进行转换.
  • 自上而下的保存和属性导航(也就是说我们在域图中保存顶级对象(此处称为Parent))
  • .Cascade.AllDeleteOrphan()在大多数情况下使用.
  • 用户独占拥有域图中的某些对象,但共享Parent的所有权.
  • Children对象上的导航属性不存在.
  • 所有类都有数字ID和数字版本字段.

使用案例:

  • 用户1启动应用程序并打开Parent.
  • 用户2启动应用程序并打开Parent.
  • 用户2添加一个孩子(此处为C2).
  • 用户2保存父母.
  • 用户1添加一个孩子(此处为C1).
  • 用户1保存父母.
  • 用户1收到StaleObjectStateException(这是正确的)

我们希望优雅地处理异常.由于用户共享父级的所有权,因此用户1应该能够成功保存,并使用他的新孩子和用户2的孩子保存父级.

根据Ayende(http://msdn.microsoft.com/en-us/magazine/ee819139.aspx),当SOSE被抛出时:

您的会话及其加载的实体是toast,因为使用NHibernate时,会话抛出的异常会将该会话移动到未定义状态.您无法再使用该会话或任何已加载的实体

已经为现在没有用的会话分配了一个ID和版本号.(我希望它没有.)

我们如何结合使用ISession.Merge()和ISession.Refresh()来获得一个同时具有C1和C2的新保存的Parent?

我们已经尝试了许多奥术排列,其中没有一个完全奏效.通常,"行已被另一个事务更新或删除(或未保存的值映射不正确")或ODBC级别的实际ID冲突.

我们的理论,目前:

  1. 重置C1上的版本号(以防止"未保存的值映射不正确")
  2. 获得一个新的会话
  3. newSession.Refresh(C1);
  4. newParent = newSession.QueryOver [...]
  5. newParent.Add(C1);
  6. newSession.SaveOrUpdate(newParent)

但是,所有文档都表明newSession.Merge 应该足够了.

用作研究的其他帖子:
Fluent NHibernate Newbie:Row被另一个事务更新或删除
是否有使用乐观锁定时不会抛出的ISession.Merge()的替代方法?
StaleObjectstateException行已更新或删除
如何告诉NHibernate只保存已更改的属性
Hibernate(JPA):如何在修改和提交多个对象时处理StaleObjectStateException(java,但相关,我认为)

nhibernate fluent-nhibernate optimistic-locking staleobjectstate

9
推荐指数
1
解决办法
1592
查看次数