我面临着其他人已经在 SO 上发布的同样问题:在从数据库读取对象时,NHibernate 会更新所有对象,因为数据库中一个字段的值不正确。
(详细来说:新添加的日期列在所有行中都包含“1/1/0001”,因此在映射时,NHibernate 会替换日期,并在 tx.Commit() 上更新每一行。)
[编辑:事实证明这是错误的。相反,这些日期字段为空,但会被 NHibernate 更新为 1/1/0001。详情请参阅迭戈的回答。]
为了防止这种情况发生,我发现这个帖子 https://stackoverflow.com/questions/673564/nhibernates-automatic-dirty-checking-update-behaviour-turning-it-off与本·谢尔曼的回答 https://stackoverflow.com/questions/673564/nhibernates-automatic-dirty-checking-update-behaviour-turning-it-off/673687#673687以及OP 提到的博客评论 http://brian.pontarelli.com/2007/04/03/hibernate-pitfalls-part-2/#comment-3403.
评论者克里斯蒂安说:
您还可以通过使用 session.setReadOnly(o, true) 禁用 Hibernate 中的快照或使用 query.setReadOnly(true) 禁用所有查询对象来禁用自动脏检查和更新。
(请注意,这篇博文是关于 Java Hibernate 的。)
query.SetReadOnly(true) 在我使用查询的地方是成功的。不过,我也有这样的代码:
ISession session = this.NHibernateHelper.SessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();
try
{
BO resultBO = session.Get<BO>(id);
tx.Commit();
return resultBO;
}
catch (Exception ex)
{
tx.Rollback();
throw ex;
}
finally
{
session.Close();
}
在这种情况下,我没有查询,并且所说的Session.SetReadOnly(resultBO, true)
NHibernate 中不存在。它去哪儿了?
我想“驱逐”基本上不是一个好主意,因为它使对象变得短暂,所以我不能用它来更新另一个会话中的值(至少它变得更复杂。我还需要确保所有对象始终被驱逐所以我的通用更新方法不需要区分持久对象和瞬态对象 -或者我完全错了?
谢谢和欢呼,
奇科多罗