Nhibernate刷新导致更新的地方应该没有 [英] Nhibernate Flush causing Updates where there should be none
问题描述
我正在使用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
认为这些值已被更改,并导致更新。
解决方案:
- 使用
nullable数据类型
来为你的类道具添加
?
- 将你的属性映射为
Not Null
类型,但是这在
中是不可取的
- 我正在使用的解决方案:我将默认值分配给实体构造函数中的
道具,所以不是保存Null
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:
- Use
nullable datatypes
for your class props by post fixing them with?
but for me this is causing other problems. - Map your properties as
Not Null
Types but this is not preferable in most cases. - 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 theDb
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屋!