This is most probably because the surrounding transaction commits, even an exception is thrown. Or you catches the exception later on and hide the error from the surrounding transaction. The update could be performed by NH whenever it flushes the session, for instance before executing queries. Committing always synchronizes the memory state to the database.
Update is only needed for instances which are not in the session yet (but in the database). Everything in the session is synchronized to the database, any any point in time, at the latest when committing.
One of the advantages of NH is what is called "persistence ignorance". This means, after instances are loaded to memory, you logic doesn't care about persistency anymore. You're using your classes like any other, at the end everything will be persisted (or rolled back) in an atomic way.
So what does this all mean for your code?
- Write your code as if there weren't NHibernate or persistency. This will also enhance maintainability and testability.
- What you are doing in memory is definitive. You don't have a second "store" step. Don't do things you don't want to do.
- Your memory needs to be as consistent as the database. Your logic is always based on memory state (eg. calculations). Inconsistent memory will break consistency of the application. So you shouldn't commit when you have data in memory you don't want in the database.
- Commit is all or nothing. Either you are happy with your changes or you roll back everything.
- Exception handling is tricky. It's not always easy to decide if you can carry on with the transaction.
- Changing the state of the entity is responsibility of your business logic. NHibernate will not "reset" a single instance. (There is a Refresh, but it will not work here and you shouldn't use it anyway). So if you want to reset a value, you need to write business logic which resets the value.