This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.
When working with an NHibernate session (the ISession instance), any changes you make – saving, updating, deleting entities – are only executed when the session is flushed. When the actual flushing occurs depends on the session’s flush mode (the FlushMode property). This mode can be one of the following:
- Never: changes are never flushed automatically, you must call ISession.Flush() explicitly;
- Commit: changes are sent as soon as the current ITransaction is committed, no need to call Flush();
- Auto: the session is flushed if a query is requested for some entity type and there are dirty local entity instances, no need to call Flush(); this is the default;
- Always: the session is flushed before any query is executed, also no need to call Flush().
What this means is: depending on the current flush mode, your changes may not reach the database at all (if you are using modes Never and forget to call Flush() or Commit and you do not commit your transaction) or you may be sending changes before you actually want to do it (if using Auto and you execute a query over some entity’s type for which you have pending local changes or Always).
So, for speed, choose Never, for better state synchronization, choose Always or Auto and for using transactions, choose Commit. And don’t forget to monitor what’s going on (using log4net, for example) and to code accordingly to your decision.