我试图插入具有Identity Id列的表,但是我一直收到异常;
NHibernate.AssertionFailure:APP.Domain.Entity.EntityName条目中的ID为null(在发生异常后不要刷新Session)
我在事务的提交点和回滚点都使用了session.Flush()
,之后一切似乎都工作了一会儿,然后异常又开始了。
using (var tranx = _session.BeginTransaction())
{
try
{
Entity entityName = new Entity();
entityName.propert1 = propert1.value;
entityName.propert2 = propert2.value;
entityName.propert3 = propert3.value;
entityName.propert4 = propert4.value;
_session.Save(entityName);
.....
other transactions
.....
tranx.Commit();
_session.Flush();
}
catch (Exception ex)
{
tranx.Rollback();
_session.Flush();
}
}
我希望在数据库表中插入一条记录,并为其自动生成一个ID,但我却得到了日志;
答案 0 :(得分:0)
从下面的问题代码中:
_session.Save(entityName);
.....
other transactions
.....
tranx.Commit();
_session.Flush();
您似乎在一项事务中正在执行多项操作-确定;称为工作单元。
然后,在您的catch
块中,您将像下面那样回滚事务(终止UoW):
catch (Exception ex)
{
tranx.Rollback();//<--This is OK
_session.Flush();//<--Why this? Remove this line.
}
那也行。但随后,您将刷新ISession
。为什么呢?
您的using块将正确处理会话。我看不到在catch
块中刷新会话有任何好处。您应该删除该行。
您提到的异常:
NHibernate.AssertionFailure:APP.Domain.Entity.EntityName条目中的ID为null(在发生异常后不要刷新Session)
不是真正的例外。真正的例外发生在那之前。您正在catch
块中使用异常。更好的方法是将catch
块修改为 handle (记录异常可能并重新抛出(带有throw;
原始异常))该异常。如果您无法处理该异常,则只需删除try-catch
块,然后将该异常扔到外面即可;来电者应处理。无论如何,您的using
块都会处置ISession
-如果未提交,也会回滚事务。
我希望在数据库表中插入一条记录,并为其自动生成一个ID,但我却得到了日志
如上所述,您真正的例外正在被静默消耗。因此,我们无法告诉您为什么这种情况没有发生。实施上述措施,您将自己了解原因。
NHibernate异常后为什么不Flush
?
工作单元是非常复杂的系统。它跟踪所有已加载实体的更改。 NHibernate做了大量工作,以使该内存实体副本与基础RDBMS保持一致。 Flush
(或其他自动刷新方式)将使用内存更改来更新RDBMS。抛出NHibernate异常时,不能保证此状态不再处于一致状态。这就是NHibernate建议处置会话并从头开始的原因。