Nhibernate Flush工作提交不 [英] Nhibernate Flush works commit doesn't

查看:90
本文介绍了Nhibernate Flush工作提交不的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很抱歉,如果我的问题没有太多细节,但是我是新来的hibernate,所以不确定如何措辞.我想知道为什么在Web应用程序中调用会话刷新不会引发错误,而提交会引发错误.

我通常有以下代码:

session.SaveOrUpdate(item);
session.Flush();

但是如果我调用session.Commit()我会得到a different object with the same identifier value was already associated with the session错误

提交"和冲洗"功能不一样吗?

解决方案

在以下情况下,您遇到的NonUniqueObjectException被抛出:

  • 当前的 ISession实例被调用以通过id获取,例如.Get<TEntity>(id),并且始终引用此项目A
  • 相同 ISession实例被调用以保留(SaveOrUpdate)一个项目B ,并且
    • 两个项目都具有相同的键(itemA.ID == itemB.ID)
    • 都是不同的引用(itemA != itemB)

因此,如果发生这种情况,则会抛出NonUniqueObjectException (具有相同标识符的另一个对象...").

Flush()及其通过FlushMode进行的配置是分离的持久层概念的实现.我们正在与session工作/交互,调用Read操作(通常立即执行或由缓存提供),调用Write操作-已排队. 执行. 向数据库引擎发出了INSERT,UPDATE,DELETE.

仅当调用Flush()时,会话才对数据库所做的更改同步". (很多优点)的优点是NHibernate可以管理写语句的顺序. 请参阅:

9.6.冲洗

发布声明的顺序:

  • 所有实体插入,使用ISession.Save()
  • 以相同的顺序保存了相应的对象
  • 所有实体更新
  • 所有收藏夹删除
  • 所有集合元素的删除,更新和插入
  • 所有集合插入
  • 所有实体删除,以相同的顺序使用ISession.Delete()
  • 删除相应的对象

最后,这是枚举的摘录 FlushMode ,它确实配置了Flush()调用:

/// <summary> Represents a flushing strategy.</summary>
/// <remarks>
/// The flush process synchronizes database state with session state by detecting state
/// changes and executing SQL statements
/// </remarks>
[Serializable]
public enum FlushMode
{
    /// <summary>
    /// Special value for unspecified flush mode (like <see langword="null" /> in Java).
    /// </summary>
    Unspecified = -1,
        /// <summary>
    /// The <c>ISession</c> is never flushed unless <c>Flush()</c> is explicitly
    /// called by the application. This mode is very efficient for read only
    /// transactions
    /// </summary>
    Never = 0,
        /// <summary>
    /// The <c>ISession</c> is flushed when <c>Transaction.Commit()</c> is called
    /// </summary>
    Commit = 5,
        /// <summary>
    /// The <c>ISession</c> is sometimes flushed before query execution in order to
    /// ensure that queries never return stale state. This is the default flush mode.
    /// </summary>
    Auto = 10,
        /// <summary>
    /// The <see cref="ISession"/> is flushed before every query. This is
    /// almost always unnecessary and inefficient.
    /// </summary>
    Always = 20
}

Sorry if my question doesn't have much detail but I'm new to nhibernate so not sure how to phrase. I'm wondering why calling session flush in a web application would not throw an error but Commit would.

I have this code normally:

session.SaveOrUpdate(item);
session.Flush();

but if I call session.Commit() I get a different object with the same identifier value was already associated with the session error

Doesn't Commit and Flush work the same?

解决方案

The NonUniqueObjectException, you are experiencing, is thrown in scenarios, when:

  • the current ISession instance was called to get by id, e.g. .Get<TEntity>(id), and it keeps reference to this item A
  • the same ISession instance is called to persist (SaveOrUpdate) an item B and
    • both items have the same key (itemA.ID == itemB.ID)
    • both are different references (itemA != itemB)

So, if this happens, the NonUniqueObjectException ("a different object with the same identifier...") is thrown.

The Flush() and its configuration via FlushMode is the implementation of the concept of the detached persistence layer. We are working/interacting with a session, calling Read operations (mostly executed immedietly or provided from cache), calling Write operations - which are queued. Not executed. No INSERT, UPDATE, DELETE is issued into DB engine.

Only when the Flush() is called, the session does the "synchronization" of the changes to DB. The advantage (one of many) is that NHibernate can manage the order of the write statements. See:

9.6. Flush

The order of issued statements:

  • all entity insertions, in the same order the corresponding objects were saved using ISession.Save()
  • all entity updates
  • all collection deletions
  • all collection element deletions, updates and insertions
  • all collection insertions
  • all entity deletions, in the same order the corresponding objects were deleted using ISession.Delete()

And finally, this is a snippet of the enum FlushMode, which does configure the Flush() call:

/// <summary> Represents a flushing strategy.</summary>
/// <remarks>
/// The flush process synchronizes database state with session state by detecting state
/// changes and executing SQL statements
/// </remarks>
[Serializable]
public enum FlushMode
{
    /// <summary>
    /// Special value for unspecified flush mode (like <see langword="null" /> in Java).
    /// </summary>
    Unspecified = -1,
        /// <summary>
    /// The <c>ISession</c> is never flushed unless <c>Flush()</c> is explicitly
    /// called by the application. This mode is very efficient for read only
    /// transactions
    /// </summary>
    Never = 0,
        /// <summary>
    /// The <c>ISession</c> is flushed when <c>Transaction.Commit()</c> is called
    /// </summary>
    Commit = 5,
        /// <summary>
    /// The <c>ISession</c> is sometimes flushed before query execution in order to
    /// ensure that queries never return stale state. This is the default flush mode.
    /// </summary>
    Auto = 10,
        /// <summary>
    /// The <see cref="ISession"/> is flushed before every query. This is
    /// almost always unnecessary and inefficient.
    /// </summary>
    Always = 20
}

这篇关于Nhibernate Flush工作提交不的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆