Problem with Session.Flush - updating entity that was never updated

115 views
Skip to first unread message

Billy Stack

unread,
Feb 24, 2010, 8:06:43 AM2/24/10
to nhu...@googlegroups.com
All,

I have the following scenario:

Start Unit of work (SessionFactory.OpenSession())

Get collection of Entities (e.g. 10 in size) from db

Update only one entity

Dispose the Unit of work (Where we call ISession.Flush())


The problem I am finding is that 10 update statements are generated -
one for each entity in the collection, even though I only actually
updated one entity.

How does NHibernate think that objects in the collection are dirty
even though they weren't updated?
I am using nullable types, is this the issue?
Ref: http://stackoverflow.com/questions/34852/nhibernate-session-flush-sending-update-queries-when-no-update-has-occurred

Is this the right way to be using the Session, should I be calling
Session.SaveOrUpdate() ?

Any help greatly appreciated...

Fabio Maulo

unread,
Feb 24, 2010, 8:22:31 AM2/24/10
to nhu...@googlegroups.com
You have Ghosts.

A ghost may appear because, wrong mapping, stale data (null in DB and not nullable property) and so on

2010/2/24 Billy Stack <bs.s...@gmail.com>

--
You received this message because you are subscribed to the Google Groups "nhusers" group.
To post to this group, send email to nhu...@googlegroups.com.
To unsubscribe from this group, send email to nhusers+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/nhusers?hl=en.




--
Fabio Maulo

Billy Stack

unread,
Feb 24, 2010, 10:27:29 AM2/24/10
to nhu...@googlegroups.com
I have traced the call even when the update is unexpected:

public override bool OnFlushDirty(object entity, object id, object[]
currentState, object[] previousState, string[] propertyNames,
NHibernate.Type.IType[] types)
{
return base.OnFlushDirty(entity, id, currentState, previousState,
propertyNames, types);
}

I inspected all currentState and previousState and they are exactly the same.
Why would NHibernate attempt to perform OnFlushDirty when "no" state
whatsoever has changed?

Billy Stack

unread,
Feb 24, 2010, 12:03:44 PM2/24/10
to nhu...@googlegroups.com
Solved the problem.

We have an IUserType to map DateTimeOffset properties in UTC in our
code to columns of datetime (No datetimeoffset type exists in SQL
Server 2005)
The Equals method was implemented incorrectly.

Every time the Equals method is called by NH to check for dirty
objects, the equals method was returning false even if though the
DateTimeOffset values were the same.

With this fix in place, the session when autoflushed now only updates
entities that were updated, and does not update entities that were not
updated!

Fabio Maulo

unread,
Feb 24, 2010, 12:08:51 PM2/24/10
to nhu...@googlegroups.com
In many cases the GhostBuster should be the standard-test to test basic CRUD of each entity, believe me

2010/2/24 Billy Stack <bs.s...@gmail.com>



--
Fabio Maulo

John Davidson

unread,
Feb 24, 2010, 1:11:37 PM2/24/10
to nhu...@googlegroups.com
Thanks for reminding me that I had not built a unit test for a class where I overrode Equals :)

John Davidson

bs.s...@gmail.com

unread,
Feb 24, 2010, 1:38:25 PM2/24/10
to nhu...@googlegroups.com
Fabio, again thanks for the help.

John, we have abstracted out all logic that we have in user types - lesson learned!

Ghostbusters to the rescue :)

José F. Romaniello

unread,
Feb 24, 2010, 2:00:24 PM2/24/10
to nhu...@googlegroups.com
Sorry for the propaganda, but i've an update for ghostbuster:


This version show you the conflictive columns, the previous and new state.

2010/2/24 <bs.s...@gmail.com>
Fabio, again thanks for the help.

John, we have abstracted out all logic that we have in user types - lesson learned!

Ghostbusters to the rescue :)

--
Reply all
Reply to author
Forward
0 new messages