2012-04-12 57 views
1

我使用了Repo模式,并且设置了测试来复制我的HTTP请求,然后在测试完成后导致在工作单元上进行处置。Nhibernate Flush在应该没有的地方导致更新

看起来,在执行一个HQL语句之后,然后调用displose(这又调用flush)它导致跨越各个元素的更新。

很bizzare--有没有人遇到过这个?

这是我的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 
+0

我可以问你如何观察到延迟加载发生? – Rippo 2012-04-12 12:55:29

+0

我正在通过NHibernate profiler来观察它 - 这个问题似乎已经消失了,现在正在被更新语句尝试被调用 - 我只是有一个HQL语句被执行 - 我将编辑我的问题以适应。 – 2012-04-12 15:39:49

回答

4

我遇到过类似的问题。我会先告诉你这是什么原因。当NHibernateDB中获取一个实体时,它会为它的道具赋值。很少有道具在DB中有空值,但在类定义中不是Nullable类型。所以NHibernate分配给他们一个默认值,例如。 0intDateTime.MinValuedatetime等当你调用commit的事务,NHibernate重新检查属性的值与DB值,自应该有Null值现在有一个默认值的道具,NHibernate认为价值已改变,导致更新。

解决方案:

  1. 使用nullable datatypes以邮递类的道具与 ?固定他们,但对我来说这是造成其他问题。
  2. 将您的物业地图设为Not Null类型,但在大多数情况下,这不是优选的 。
  3. 我使用的解决方案:我指定的默认值在实体的构造函数中 道具,所以不是在DbNhibernate节省Null值 节省一些默认值,这将停止 调用不必要的更新。

您可以通过google NHibernate ghostbuster进一步了解此问题。

+0

完美!尽管刚刚过了一年......但这完全描述了这个问题!现在一切都使用Nullable(),我们也关闭了NH中的TrackChanges功能 – 2013-04-17 14:37:35

1

NHibernate的通常运行更新时有短暂的或分离的实体,它是不知道。也就是说,它不知道它是否拥有父项来管理它的实体,或者它不确定该实体是否脏。这通常是某个地方出现错误映射的症状(对某些父节点缺少反转),或者实体上没有版本或日期列。

相关问题