Nhibernate Flush works提交不';T
抱歉,如果我的问题没有太多细节,但我是nhibernate的新手,所以不知道如何表达。我想知道为什么在web应用程序中调用sessionflush不会抛出错误,而Commit会抛出错误 我通常有以下代码:Nhibernate Flush works提交不';T,nhibernate,Nhibernate,抱歉,如果我的问题没有太多细节,但我是nhibernate的新手,所以不知道如何表达。我想知道为什么在web应用程序中调用sessionflush不会抛出错误,而Commit会抛出错误 我通常有以下代码: session.SaveOrUpdate(item); session.Flush(); 但是如果我调用session.Commit(),我会得到一个具有相同标识符值的不同对象已经与session关联了 提交和刷新的工作原理不一样吗?似乎是因为我使用了FlushMode.Commit而不是F
session.SaveOrUpdate(item);
session.Flush();
但是如果我调用session.Commit(),我会得到一个具有相同标识符值的不同对象已经与session关联了
提交和刷新的工作原理不一样吗?似乎是因为我使用了FlushMode.Commit而不是FlushMode.Auto。无法100%确定在以下情况下,为什么会在场景中引发您正在经历的
UnonqueObjectException
:
- 调用当前ISession实例以按id获取,例如,
,它保留对该项A的引用.get(id)
- 调用相同的ISession实例来持久化(
)项B,并且SaveOrUpdate
- 这两个项具有相同的键(
)itemA.ID==itemB.ID
- 两者都是不同的引用(
)itemA!=itemB
- 这两个项具有相同的键(
ununiqueObjectException
(“具有相同标识符的不同对象…”)
Flush()
及其通过FlushMode
的配置是分离持久层概念的实现。我们正在与一个会话
进行工作/交互,调用读取
操作(大部分是立即执行的或从缓存中提供的),调用写入
操作-这些操作是排队的未执行否将插入、更新、删除发布到数据库引擎中
只有在调用Flush()
时,会话才会对数据库的更改进行“同步”。优点(众多优点之一)是NHibernate可以管理写入语句的顺序。见:
发表声明的顺序:
- 使用
ISession.Save()
- 所有实体更新
- 所有集合删除
- 所有集合元素的删除、更新和插入
- 所有集合插入
- 所有实体删除,使用
ISession.Delete()
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
}
///表示刷新策略。
///
///flush进程通过检测状态来同步数据库状态和会话状态
///更改和执行SQL语句
///
[可序列化]
公共枚举刷新模式
{
///
///未指定刷新模式的特殊值(如Java中)。
///
未指定=-1,
///
///除非明确指定Flush(),否则不会刷新ISession
///由应用程序调用。此模式对于只读非常有效
///交易
///
从不=0,
///
///调用Transaction.Commit()时,ISession将被刷新
///
提交=5,
///
///有时在执行查询之前刷新ISession,以便
///确保查询永远不会返回过时状态。这是默认的刷新模式。
///
自动=10,
///
///在每次查询之前刷新。这是
///几乎总是不必要和低效的。
///
始终=20
}
非常彻底和权威的回答。现在唯一奇怪的是,如果我设置FlushMode.Auto,我在执行session.Transaction.Commit时不会出现该错误,但在执行FlushMode.Never时,调用session.Flush(),然后执行session…Commit,我会出现错误。你知道为什么吗?一般来说,我强烈建议:在提交之前使用1)提交或2)从不使用显式Flush()。写入操作应位于一个会话中,读取操作应位于另一个会话中(例如,不同的web请求)。是否应该提交整个操作。因此,汽车通常不是最好的方式。我会说。我一直在使用“永不”和“显式”刷新。。。