2013-06-20 15 views
2
NHibernate version: 3.3.2. 

我有一个NHibernate事务,有几个操作。作为事务中的一个中间步骤,我尝试通过Session.Save插入一个带有自动增量PK的新实体实例。当保存错误并且自动增量Id尚未生成时如何从会话中删除实体

在某些情况下,由于违反了外键值而导致插入错误。我发现这个异常是为了做一些日志记录并忽略它,假设插入操作没有完成,并继续执行以下步骤。这是一项功能要求,不能更改。根据性能要求,在插入之前验证值也不是可接受的解决方案。

我的问题:非持久实体已被添加到NH会话缓存但具有空Id。所以,后来我得到这个例外,做一些其他的NH操作时:

NHibernate.AssertionFailure: null id in MyApp.MyPackage.MyClass entry (don't flush the Session after an exception occurs) 

我的问题:我怎么能拉这恼人的“僵尸”实体关闭会话,所以我成功可以不惜一切结束提交事务脚步?

我不能退出,因为Id是空的。

我试了一下,得到了以下异常:

System.InvalidOperationException: cannot generate an EntityKey when id is null 

我也不能作为Clear()我在交易的中间,有一些之前和之后的步骤在当前会话中保存。

我得到的最初的例外有点令人困惑,并且引发了与真正问题发源地不同的地方。这个链接给了我一些信息,找出发生了什么:NHibernate - null id in entry (don't flush the Session after an exception occurs)

+0

你如何驱逐它? Session.Evict(objReference)? – epitka

+0

@epitka是的,我使用调用session.Save时使用的实体实例。它具有属性Id值= 0,如果它已被正确插入,它应该由Save填充。 – Diana

回答

0

根据NHibernate Manual, 9.8. Exception handling

如果ISession的抛出一个异常,你应该立即回滚事务,调用ISession.Close(),丢弃该ISession实例。 ISession的某些方法不会使会话保持一致的状态。

我想你必须在你的情况下重新启动整个交易。

+0

最后,我不得不改变逻辑并牺牲性能来事先检查FK违规,以避免异常,因为我没有找到任何其他方式在异常后恢复会话状态。 – Diana

0

尽管它很糟糕,我已经能够通过在'try/catch'中包装我的zombie.discard()来解决这个问题,并且当我这样做的时候,它会在你的对象条目中抑制更糟糕的“空id”(发生异常时不要刷新会话)“

我觉得脏。

+0

在我的情况下没有运气,即使会话被破坏。不管怎么说,还是要谢谢你! – Diana

相关问题