【问题标题】:Nhibernate Flush causing Updates where there should be noneNhibernate Flush 导致不应存在的更新
【发布时间】:2012-04-12 12:22:39
【问题描述】:

我正在使用 Repo 模式,并且我已经设置了测试来复制传入的 HTTP 请求,然后在测试完成后导致对工作单元进行处置。

似乎在执行 HQL 语句后,然后调用 displose(这反过来又调用 flush)会导致跨各种元素的更新。

非常奇怪 - 以前有人遇到过这种情况吗?

这是我的 HQL 语句,它正在执行:

_session.CreateQuery("select distinct t from TaskEntity as t").List<T>()

我已将其恢复为最简单的形式 - 请注意 HQL 语句并不直接在 CreateQuery 中。

这是我得到的堆栈跟踪:

BM.Data.Informix.IfxParameterCollection.b(Int32 A_0)
IBM.Data.Informix.IfxParameterCollection.GetParameter(Int32 index)
System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item(Int32 index)
NHibernate.Type.Int32Type.Set(IDbCommand rs, Object value, Int32 index)
NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value, Int32 index)
NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, Object value, Int32 index, ISessionImplementor session)
NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index)
NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session)
NHibernate.Action.EntityUpdateAction.Execute()
NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
NHibernate.Engine.ActionQueue.ExecuteActions()
NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event)
NHibernate.Impl.SessionImpl.Flush()
Case.Data.SQL.NHibernateUnitOfWork.Dispose() in C:\Projects\Case System\Dev\WorkingBranch\Src\Case.Data.SQL\NHibernateUnitOfWork.cs: line 46
Case.Domain.Tests.TaskServicesTests.TakeDown() in C:\Projects\Case System\Dev\WorkingBranch\Src\Case.Domain.Tests\TaskServicesTests.cs: line 40

【问题讨论】:

  • 请问您是如何观察到延迟加载发生的?
  • 我正在通过 NHibernate 分析器观看它 - 问题似乎已经消失,现在正被试图调用的更新语句所取代 - 我只是执行了一个 HQL 语句 - 我将编辑我的适合的问题..

标签: nhibernate fluent-nhibernate nhibernate-mapping


【解决方案1】:

我遇到了类似的问题。我先告诉你这是什么原因造成的。当NHibernateDB 获取实体时,它会将值分配给它的道具。 DB 中很少有具有空值但在类定义中不是 Nullable 类型的道具。所以NHibernate 为它们分配了一个默认值,例如。 0 用于intDateTime.MinValue 用于datetime 等。当您在事务上调用提交时,NHibernate 重新检查具有DB 值的属性的值,并且因为道具现在应该具有Null 值有一个默认值,NHibernate 认为值已更改并导致更新。

解决方案:

  1. nullable datatypes 用于您的班级道具,方法是使用 ? 但对我来说这会导致其他问题。
  2. 将您的属性映射为Not Null 类型,但这在 大多数情况。
  3. 我正在使用的解决方案:我将默认值分配给 props 在实体的构造函数中,所以不是保存 Null 值 在 Db Nhibernate 中保存一些默认值,这会停止 调用不必要的更新。

您可以进一步谷歌NHibernate ghostbuster 以了解有关此问题的更多研究。

【讨论】:

  • 完美!尽管仅仅过了一年多……但这完美地描述了这个问题!现在一切都使用 Nullable(),我们还关闭了 NH 中的 TrackChanges 功能
【解决方案2】:

NHibernate 通常在它有不确定的瞬态或分离实体时运行更新。也就是说,它不知道它是否有管理它的父实体或者它不确定实体是否脏的实体。这通常是某处映射错误的症状(某些父项上缺少 Inverse),或者您的实体上没有 Version 或 Date 列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-16
    相关资源
    最近更新 更多