1

我正在使用 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
4

2 回答 2

5

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

解决方案:

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

您可以进一步 googleNHibernate ghostbuster以获取有关此问题的更多研究。

于 2013-04-17T05:27:20.967 回答
1

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

于 2012-04-15T03:26:16.083 回答