2

I understand and accept that the identity generator breaks the unit of work because it requires an insert prior when the transaction should actually commit, described in http://fabiomaulo.blogspot.com/2008/12/identity-never-ending-story.html. I'm aware of the alternatives and why they are better (in relation to the problem at hand, and in general).

The question I have is why the implementation exists as it does, and whether or not these issues affect EF (sheer curiosity). The only real justification I have seen i: "NHibernate needs the identity because every entity in the session (they are called "persistent entities") needs to be identified. The identity is also normally used to determine if the record already exists in the database (unsaved value)."

Why must it have the value immediately, though? Why can it not defer the INSERT until the commit occurs, the commit, retrieve the value, and update the entities dependent on the returned identity, then insert/update/whatever them as well?

Less important question: does EF suffer from the same issue? I know ISession is a proper UoW implementation; does EF not implement the UoW pattern, or does it have a different way of handling this problem, and if so, what is it?

Community
  • 1
  • 1
intrepidus
  • 974
  • 2
  • 12
  • 24

1 Answers1

3

I will not tell you exactly why the insert is not deferred in NHibernate but I guess that NHibernate simply needs real entity identity immediately when you put it to the session.

EF doesn't use this approach but it doesn't mean that EF approach is better. First of all EF doesn't have built in support for identity generators. You can implement your own but it can be little bit challenging just because of issues NH is trying to avoid.

ORM tools implements identity map and they demand each entity to be uniquely identified. NH probably uses real identity immediately whereas EF can defer the identity definition and use some temporary key. This temporary key is used when the real identity is defined in the database - that means IDENTITY column in MS SQL Server. EF knows real identity only after inserting record to the database and querying SCOPE_IDENTIY(). When EF receives the real key it updates the entity and all its relations (FKs) to reflects the real identity.

This is also the biggest disadvantage of the approach - EF must insert every record in separate roundtrip to database to get its primary key value (EF doesn't support command batching anyway). Here you find the biggest difference with NH which is able to pregenerate identities using generators and batch those DML commands to single roundtrip to database.

Usage of temporary keys in EF has another side effects when you start using FK properties introduced in EF 4.0. Once FK properties are used you must explicitly set PK to some unique temporary value otherwise inserting two records with relations will fail with exception (you will have two entities with default key value and FK properties will not be able to define which one is a correct principal).

EF is designed to work with database generated keys whereas NH prefers application generated keys.

Community
  • 1
  • 1
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670