Logo

NHibernate

The object-relational mapper for .NET

Identity: The never ending story

How many times you heard us saying “don’t use identity POID generator!” ?

To understand it better you must move your mind to an application, or a use-case, where the pattern open-session-in-view (aka session-per-request) is not applicable.

The Unit of Work

The Unit of Work (UoW) is a pattern described by Martin Fowler. When you work with NHibernate the real implementation of the pattern is the NH-Session (more exactly in PersistentContext inside de session). The commit and rollback, described in the pattern, are respectively the session.Flush() and the session.Close() (the close mean when close the session without Flush it). As usual the pattern described by Fowler is short and very clear so an explication is unneeded; here I want put more emphasis in two phrases:

“You can change the database with each change to your object model, but this can lead to lots of very small database calls, which ends up being very slow.”

“A Unit of Work keeps track of everything you do during a business transaction that can affect the database. When you're done, it figures out everything that needs to be done to alter the database as a result of your work.”

In addition note, that Fowler, are talking about business transaction (repeat business-transaction).

In NHibernate, setting the FlushMode to FlushMode.Never (MANUAL in Hibernate), if you begin a NH-Transaction and commit it, but without a session.Flush, nothing happen in DB.

Analyze Session-per-conversation

SessionPerConversation

The session-per-conversation pattern is an example of a business transaction that spans multiple requests. As described by Fowler the nh-session (the real UoW) spans the whole business-transaction and in each request we are begin-commit a NH-Transaction. At the end of the conversation, inside a NH-Transaction, we will chose to Flush or Close the NH-session (mean commit or rollback the UoW).

In session-per-conversation we don’t want have a NH-Transaction (that, in this moment, mean a ADO.NET transaction) open for the whole conversation because not only is “impractical”, as said Fowler, but, in my opinion, it break the concept of ACID.

How to break all ?

If you want break the UoW pattern, and session-per-conversation pattern, you have a very easy way:use identity as your POID strategy.

The identity strategy mean :

  • change the database with each change to your object model (see the phrase above)
  • if you run a session.Save in the first request you will have a new record in the DB, and you can’t rollback this change without run an explicit Delete.

In addition I want say that using identity you are “disabling” the ADO-batcher NH’s feature for inserts.

You can continue using identity but you must know what you are loosing, and only you know what you are winning (I don’t know what you are winning using identity when you are working with a spectacular persistence layer as NHibernate is).


Posted Sun, 21 December 2008 02:38:00 AM by fabiomaulo
Filed under: identity, NHibernate, Session, Unit of Work

comments powered by Disqus
© NHibernate Community 2024