tags:

views:

2156

answers:

4

Hello,

I am kind of confused on how Flush ( and NHibernate.ISession) in NHibernate works.

From my code, it seems that when I saved an object by using ISession.Save(entity), the object can be saved directly to the database.

However, when I update and object using ISession.SaveOrUpdate(entity) or ISession.Update(entity), the object in the database is not updated--- I need to call ISession.Flush in order to update it.

The procedure on how I update the object is as follows:

  1. Obtain the object from the database by using ISession.Get(typeof(T), id)
  2. Change the object property, for example, myCar.Color="Green"
  3. Commit it back to the database by using ISession.Update(myCar)

The myCar is not updated to database. However, if I call ISession.Flush afterwards, then it is updated.

When to use Flush, and when not to use it?

+1  A: 

NHibernate will only perform SQL statements when it is necessary. It will postpone the execution of SQL statements as long as possible.

For instance, when you save an entity which has an assigned id, it will likely postpone the executin of the INSERT statement. However, when you insert an entity which has an auto-increment id for instance, then NHibernate needs to INSERT the entity directly, since it has to know the id that will be assigned to this entity.

When you explicitly call flush, then NHibernate will execute the SQL statements that are necessary for objects that have been changed / created / deleted in that session.

Flush

Frederik Gheysels
+2  A: 

In many cases you don't have to care when NHibernate flushes.

You only need to call flush if you created your own connection because NHibernate doesn't know when you commit on it.

What is really important for you is the transaction. During the transaction, you are isolated from other transactions, this means, you always see you changes when you read form the database, and you don't see others changes (unless they are committed). So you don't have to care when NHibernate update data in the database unless it is committed. It is not visible to anyone anyway.

NHibernate flushes if

  • you call commit
  • before queries to ensure that you filter by the actual state in memory
  • when you call flush

Example:

using (session = factory.CreateSession())
using (session.BeginTransaction())
{
  var entity = session.Get<Entity>(2);
  entity.Name = "new name";

  // there is no update. NHibernate flushes the changes.

  session.Transaction.Commit();
  session.Close();
}

The entity is updated on commit. NHibernate sees that your session is dirty and flushes the changes to the database. You need update and save only if you made the changes outside of the session. (This means with a detached entity, that is an entity that is not known by the session).

Stefan Steinegger
Thanks, but when I update an object in the database, does this mean that I create my own transaction? Or else why do I need to call flush to update the database?
Ngu Soon Hui
Had to fix it: you need to flush when you created your own connection. NHibernate creates a connection for you if you call CreateSession, but you can provide you own ADO.NET connection. usually you don't need this. You don't need to call flush if you don't do this.
Stefan Steinegger
A: 

I have another question :

var entity = session.Get(2); //Search the entity entity.Name = "new name"; //Change one property value
var entityTemp = session.Get(2); //Search the entity again.This step , nHibernate will auto save the entity ?

Did you meet this problem ? I don't want the nhiberante auto save the detached object . How to config it ?

xiemails