当我从不执行session.Save时,为什么NHibernate会保存对象?

Myl*_*Rip 8 nhibernate fluent-nhibernate

我正在使用NHibernate和Fluent NHibernate.

我有代码,我开始一个事务,然后我进入一个创建几个对象的循环.对于每个对象,我检查某些条件.如果满足这些条件,则在对象上执行session.SaveOrUpdate().在循环结束时,我发出一个提交事务.

我在session.SaveOrUpdate命令上设置了断点,证明它永远不会到达(因为循环中的任何对象都没有满足条件). 然而,当事务提交时,对象被保存!

我正在使用AuditInterceptor并在OnSave方法中设置了断点.它被调用,但堆栈跟踪仅追溯到提交事务的语句.

此时没有任何类型的对象已经对它们执行了SaveOrUpdate,因此级联不能解释它.

为什么NHibernate会保存这些对象?

reb*_*ard 13

来自NHibernate ISession.Update线程:

这是正常默认行为:

Hibernate维护已插入,更新或删除的对象的缓存.它还维护从数据库中查询的对象的缓存.只要用于获取它们的EntityManager仍处于活动状态,这些对象就称为持久对象.这意味着在事务提交时,事务边界内对这些对象的任何更改都会自动保留.这些更新隐含在事务的边界内,您不必显式调用任何方法来保存值.

来自Hibernate陷阱第2部分:

问)我还需要在交易中进行保存和更新吗?

只有非持久性对象(例如新对象)才需要Save().您可以使用"更新"将已逐出的对象带回会话.

NHibernate的自动(脏检查)更新行为:

我刚刚发现,如果我从NHibernate会话中获取一个对象并更改对象的属性,NHibernate将在提交时自动更新对象而不调用Session.Update(myObj)!

答:您可以将Session.FlushMode设置为FlushMode.Never.这将使您的操作显式,即:在tx.Commit()或session.Flush()上.当然,这仍然会在提交/刷新时更新数据库.如果你不想要这种行为,那么调用session.Evict(yourObj)然后它会变成瞬态的,NHibernate不会为它发出任何db命令.


小智 5

这与会话刷新模式为FlushMode.Commit(默认)有关.提交事务时,将保存对会话中对象所做的任何更改,并且更改将保持不变.

您可以在会话中设置FlushMode属性.如果您想要只读事务,请指定FlushMode.Manual.

希望这可以帮助!