CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeffrey Palermo [MVP]

Software management consultant and CTO, Headspring Systems

NHibernate: ICriteria may cause update - know about AutoFlush mode - level 300

This topic is for those already using NHibernate.  By looking at the forum, that is a whole load of people!

As always, my blog posts stem from experience, and this is no different.  It's been a year since I first tried out NHibernate, and since then I've used it on 4 large, unrelated applications.  This latest application of NHibernate is by far the most exciting, however, because we are able to take advantage of the full power of the library.  The others have always been tempered with the few things that couldn't be changed that hampered seamless data access.  My team no longer has to slow down to think about what SQL to write.  We stay in C#, and we're going faster and faster.  For the performance-minded, the NHibernate SQL is pretty darned fast (because there is nothing special about it - just CRUD).  We run about 120 database tests in 2.5 seconds - not bad.

Last week, I learned another thing new about NHibernate - AutoFlush mode.  This is important because NHibernate only keeps 1 instance of your domain object per ISession instance, so if you ask for the same object multiple times from the same ISession instance, you'll get the same domain object instance.  Imagine this scenario: 

  • You pull some objects into memory.
  • The user modifies one object.
  • You query for a list using ICriteria (the object the user modified is a match for this list)

What should the system do?  Should the fresh query refresh all the objects and throw away the user's changes?  NHibernate's default behavior is "no".  It is configured to "autoflush" by default.  When it detects that some changes might inadvertently be thrown away by a fresh query, it will auto update the modified object to the database.  If you open up SQL Profiler, look for UPDATE commands amidst SELECTs.  If you choose to set the autoflush mode to "NEVER", then you'll get a big fat exception, and you can write some code to handle the times when you need to do a fresh query after a persistent object has been modified.



Comments

Ayende Rahien said:

The reasoning here is a bit more complex. The issue is that NH doesn't know if your changes may modify the query results. Trying to find out in memory is extremely difficult, so it defaults to saving everything to the database and letting it sort it out. Setting the flush mode to never is not really something you want to do, since it only makes sense when you want to execute your own SQL statement (and commit those) and commit changes in NHibernate's session in a seperate transaction. Usually, setting this to Commit is a good choice.
# October 23, 2006 2:51 PM

About Jeffrey Palermo

Jeffrey Palermo is a software management consultant and the CTO of Headspring Systems in Austin, TX. Jeffrey specializes in Agile coaching and helps companies double the productivity of software teams. Jeffrey is an MCSD.Net , Microsoft MVP, Certified Scrummaster, Austin .Net User Group leader, AgileAustin board member, INETA speaker, INETA Membership Mentor, Christian, husband, father, motorcyclist, Eagle Scout, U.S. Army Veteran, and Texas A&M University graduate. Check out Devlicio.us!

This Blog

Syndication