tags:

views:

244

answers:

1

When I update (with a flush) one record in a list of records retrieved from the database nHibernate is versioning all of the records that were in the original list.

Retrieving a list of records from the database:

using(UnitOfWork.Start())
{
   queuedJobs = aJobServiceManager.GetAllJobs().Where(aJob => aJob.Status == PricingStatus.QUEUED).ToList();
}

/* Do some work on the record*/
using(UnitOfWork.Start())
{
   //aJob is a record from queuedJobs.
   aJobServiceManager.Save(aJob);
   //When Flush is called I'm expecting only aJob to be updated in the database.
   //aJob is correctly updated BUT
   //All the other records in queuedJobs are also updated (their version field is incremented).
   UnitOfWork.Current.Flush();
}

Why is nHibernate updating all the records when they haven't changed and how do you stop this behavior?

+2  A: 

This is most likely the problem you're running into: http://nhforge.org/blogs/nhibernate/archive/2008/10/20/how-test-your-mappings-the-ghostbuster.aspx

It would help to see your mapping file for job. If you're doing something like

< property name="Status" type="int" />

Where Status is actually StatusEnum you'll end up with ghosting.

ShaneC
So Flush() tries to write all "dirty" objects to the database and not just the ones that I've explicitly called "Save()" on?
brainimus
Yes. But what "dirty" means can be a bit confusing. For instance you have Job.Status which is stored as I assume an integer in the database but is an enum in the object model. NHibernate will see this difference as "dirty" even if the values match.
ShaneC
Unfortunately at this point I can't post the entire mapping file since it contains sensitive items. I can say though that the example for the Status property that you have is what I had. I have since changed the mapping to point to an int field in my job class and the property handles converting this to the enum. It might be worthwhile to note that the job contains a bag of other objects that used the same enum but I have also made the mapping file update a field in the class and a property converts the field to the enum. I'm still having the same issue though.
brainimus
After much digging I have found the second place where this was occurring. In my mapping file I had a value in the database mapped to a property. In my class though the setter for the property assigned the value to a private variable like so: set{ thePrivateVariable = value;}. Once I changed my mapping to set the private field (thePrivateVariable) directly my problem was solved.
brainimus