Nhibernate刷新导致更新的地方应该没有 [英] Nhibernate Flush causing Updates where there should be none

查看:146
本文介绍了Nhibernate刷新导致更新的地方应该没有的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


$ b $看起来,执行一个HQL语句后,然后调用displose(这反过来调用刷新),它导致跨各种元素更新。

非常bizzare - 有没有人遇到过这个?



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

  _session.CreateQuery(从TaskEntity选择不同的t作为t)。List< T>()

我已经把它拉回到最简单的形式 - 注意HQL语句并不直接在CreateQuery中。



这里是堆栈跟踪我得到:


$ b $ $ $ $ $ $ $ BM.Data.Informix。 IfxParameterCollection.b(Int32 A_0)
IBM.Data.Informix.IfxParameterCollection.GetParameter(Int32索引)
System.Data.Common.DbParameterCollecti on.System.Collections.IList.get_Item(Int32 index)
NHibernate.Type.Int32Type.Set(IDbCommand rs,Object value,Int32 index)
NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd,Object值,Int32索引)
NHibernate.Type.NullableType.NullSafeSet(IDbCommand st,对象值,Int32索引,ISessionImplementor会话)
NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id,Object [] fields对象rowId,布尔[] includeProperty,布尔[] [] includeColumns,Int32表,IDbCommand语句,ISessionImplementor会话,Int32索引)
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 oldVers离子,对象obj,SqlCommandInfo sql,ISessionImplementor会话)
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可执行文件)
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()在C:\Projects\Case System\Dev\WorkingBranch\Src\Case.Data .SQL \NHibernateUnitOfWork.cs:第46行
Case.Domain.Tests.TaskServicesTests.TakeDown()in C:\\ Projects \ Case System \Dev\WorkingBranch\Src\Case.Domain.Tests\TaskServicesTests.cs:line 40


解决方案

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



解决方案:


  1. 使用 nullable数据类型来为你的类道具添加

  2. 将你的属性映射为 Not Null 类型,但是这在
    中是不可取的
  3. 我正在使用的解决方案:我将默认值分配给实体构造函数中的
    道具,所以不是保存 Null
  4. code $ values
    Db Nhibernate 中保存了一些默认值, $ b调用不必要的更新。

您可以继续使用 NHibernate ghostbuster 更多的研究这个问题。

I am using the Repo pattern, and I have set up tests to replicate my a HTTP request coming in and then causing dispose on a unit of work once a test has completed.

It appears that after executing a HQL statement, and then calling displose (which in turn calls flush) that it is causing an update across various elements.

Very bizzare - has anyone come across this before?

Here is my HQL statement and it's execution:

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

I've pulled this back to it's simplest form - and note the HQL statement is not directly in the CreateQuery.

Here is the stack trace I am getting:

I

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

解决方案

I faced a similar problem. I'll first tell you what causes this. When NHibernate fetches an entity from the DB it assigns values to it's props. There are few props that have null values in the DB but are not of Nullable type in the class definition. So NHibernate assigns them a default value eg. 0 for int, DateTime.MinValue for datetime etc. When you call commit on the transaction, NHibernate rechecks the values of properties with DB values and since props which should have had Null values now have a default value, NHibernate thinks that the values have been changed and causes an update.

Solution:

  1. Use nullable datatypes for your class props by post fixing them with ? but for me this is causing other problems.
  2. Map your properties as Not Null Types but this is not preferable in most cases.
  3. The solution that I am using: I am assigning default values to the props in the entity's constructor, so instead of saving Null values in the Db Nhibernate saves some default value and this stops the calls to unnecessary updates.

You may further google NHibernate ghostbuster for more research on this problem.

这篇关于Nhibernate刷新导致更新的地方应该没有的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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