NHibernate makes db changes without an explicit call to save or update

I am using Nhibernate 2.0 in ASP.NET. I start a transaction when requesting a page and commit the transaction at the end. During the page: - I get the object - I change the property of the object - I check the object - if the check is correct, I call save-update on this object - if the check is incorrect, I do not call save-update on this object - I always make a transaction at the end of the page.

The problem is that also, when the check is incorrect, and I do not make any calls to save the updates to the object, the commit transaction will commit a change to the database.

I set FlushMode to Never, but nothig changed.

Have a suggestion? What am I wrong?

+7
nhibernate
source share
3 answers

During page: - I get an object

If you get an object from a session, you misunderstand Update. The update is intended to join an existing object to the session. If you get an entity from a session, it is already tied to that session, so updating does not make sense.

SaveOrUpdate vs. Update in this case does not matter - the same.

NHibernate tracks object changes in a session. When you make a transaction or clear a session, it checks for any changes (which are), and then commits them to the database. The thing is that it's not your job to keep track of which objects are changed (dirty), these are NHibernates.

Other ORMs may require that you yourself track changes and invoke some update explicitly on any changed object that you want to save, but NH does not work that way.

So, to answer your question, if the verification fails, you do not want to complete the transaction.

NH is also fixed in relation to the unit of work pattern. Therefore, if you are committing to another logical part of the program from your business logic, which checks the operation, this is likely to cause friction.

+17
source share

I ran into this problem. Eyston's answer was very helpful, explaining that it doesn't matter if you call ISession.Update (object) or SaveOrUpdate (object), NH keeps track of changes, and committing the transaction will commit the changes.

There are several ways you can perform your validation to prevent changes to the database. Perform all your validation and (possibly) saving in a separate transaction.

using (ITransaction tx = session.BeginTransaction()) { // get your object // do your validation // if you pass validation: tx.Commit(); // if not, roll it back tx.Rollback(); } 

I solved my problem a little differently. If my check fails, I don't want any updates to occur for this particular object, so I just log out of the session.

 if (!myObj.ValidateForSave()) { session.Evict(myObj); } 

By doing this, you can stick to your only transaction, starting at the top of the page and ending at the end. If your object does not pass validation, it will not be in the session and no changes will be saved to the database.

+5
source share

The solution that works for me in this case is:

  • Set the FlushMode session parameter to Commit.

  • Remove all references to "Flush" in the code by processing updates in memory in the object.

  • Always open 1 transaction per session when saving and then drop that session.

+1
source share

All Articles