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.

This entry was posted in Data Access, Learning, Tips & Tricks. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

One Response to NHibernate: ICriteria may cause update – know about AutoFlush mode – level 300

  1. 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.

Leave a Reply