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

发布于 2024-10-22 19:01:22 字数 434 浏览 2 评论 0原文

我正在使用 NHibernate 和 Fluent NHibernate。

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

我在 session.SaveOrUpdate 命令上设置了一个断点,证明它从未到达(因为循环中的任何对象都没有满足条件)。 尽管如此,当提交事务时,对象会被保存!

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

此时没有任何类型的对象对其执行过 SaveOrUpdate,因此级联无法解释它。

为什么 NHibernate 保存这些对象?

I'm using NHibernate with Fluent NHibernate.

I have code where I start a transaction, then I enter a loop which creates several objects. For each object I check certain conditions. If these conditions are met, then I execute a session.SaveOrUpdate() on the object. At the end of the loop, I issue a commit transaction.

I have a breakpoint set on the session.SaveOrUpdate command, proving that it is never reached (because the conditions have not been met by any of the objects in the loop). Nevertheless, when the transaction is committed, the objects are saved!

I am using an AuditInterceptor and have set a breakpoint in the OnSave method. It is being called, but the stack trace only traces back to the statement that commits the transaction.

There are no objects of any kind that have had SaveOrUpdate executed on them at this point, so cascading doesn't explain it.

Why is NHibernate saving these objects?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忱杏 2024-10-29 19:01:22

来自 NHibernate ISession.Update 线程:

这是 正常默认行为

Hibernate 维护对象的缓存
已插入、更新或
已删除。它还维护一个缓存
已查询的对象
数据库。这些对象是
称为持久对象
只要 EntityManager 是
用于获取它们仍然处于活动状态。
这意味着任何改变
这些对象在 a 的范围内
交易是自动进行的
事务处理时持久化
坚定的。这些更新是隐式的
在交易范围内
并且您不必显式调用
任何保存值的方法。

来自 Hibernate 陷阱第 2 部分

问)我还需要保存并
更新内部交易?

仅对于以下对象才需要 Save()
不持久(例如新的
对象)。您可以使用更新来带来
已被驱逐回来的对象
进入会话。

来自 NHibernate 的自动(脏检查)更新行为<强>:

我刚刚发现如果我得到一个
来自 NHibernate 会话的对象和
更改对象的属性,
NHibernate会自动更新
没有我的情况下提交的对象
调用 Session.Update(myObj)!

答案:您可以将 Session.FlushMode 设置为
FlushMode.Never。这将使您的
显式操作,即:在 tx.Commit() 或 session.Flush() 上。
当然这还是会更新的
提交/刷新时的数据库。如果你这样做
不想要这种行为,然后打电话
session.Evict(yourObj) 它将
然后变成瞬态和NHibernate
不会为其发出任何数据库命令。

From NHibernate ISession.Update thread:

It's the normal and default behavior:

Hibernate maintains a cache of Objects
that have been inserted, updated or
deleted. It also maintains a cache of
Objects that have been queried from
the database. These Objects are
referred to as persistent Objects as
long as the EntityManager that was
used to fetch them is still active.
What this means is that any changes to
these Objects within the bounds of a
transaction are automatically
persisted when the transaction is
committed. These updates are implicit
within the boundary of the transaction
and you don’t have to explicitly call
any method to persist the values.

From Hibernate Pitfalls part 2:

Q) Do I still have to do Save and
Update inside transactions?

Save() is only needed for objects that
are not persistent (such as new
objects). You can use Update to bring
an object that has been evicted back
into a session.

From NHibernate's automatic (dirty checking) update behaviour:

I've just discovered that if I get an
object from an NHibernate session and
change a property on object,
NHibernate will automatically update
the object on commit without me
calling Session.Update(myObj)!

Answer: You can set Session.FlushMode to
FlushMode.Never. This will make your
operations explicit ie: on tx.Commit() or session.Flush().
Of course this will still update the
database upon commit/flush. If you do
not want this behavior, then call
session.Evict(yourObj) and it will
then become transient and NHibernate
will not issue any db commands for it.

柠檬心 2024-10-29 19:01:22

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

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

希望这有帮助!

It's to do with the sessions flush mode being FlushMode.Commit (default). When the transaction is committed any changes made to objects within the session are saved and the changes persisted.

There's a FlushMode property on the session that you can set. If you want a readonly transaction specify FlushMode.Manual.

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文