views:

239

answers:

1

I would like to implement the conversation per business transaction pattern in a WPF application as described here. Unfortunately this application has a large existing database using SQL Server generated identity keys in all tables.

I know that adding a new object to an NHibernate session will cause it to be inserted if it has an identity key. Fabio has the pattern commiting the current transaction at the end of each request, even though we haven't necesarily finished the entire unit of work yet.

If I understand correctly, this means that my objects are going to be inserted into the database and not removed even if I abandon the unit of work. So:

  • Is this pattern incompatible with identity keys?
  • Are there any reasonable work arounds?
  • Is there a better pattern I can use in this case?

Edit #1:

Some additional comments from Fabio are here.

Edit #2:

Exploring further has lead me to the persist(...) method which is similar to save(...) but just different enough to be confusing. This statement taken from the hibernate FAQs is interesting:

The persist() method also guarantees that it will not execute an INSERT statement if it is called outside of transaction boundaries. This is useful in long-running conversations with an extended Session/persistence context.

Surely if it guaranteed the same inside a transaction boundary it would be more useful? I was under the impression not using transactions was frowned upon anyway.

+1  A: 

One workaround - you can hold off on your ISession.Saves until you're ready to commit your unit of work, perhaps as a collection of transient instances in your unit of work class.

Also, if your entities are referenced by an existing entity (and it makes sense to), you can cascade the inserts - done consistently, this means you should only need to explicitly insert your aggregate root objects. This is the approach I normally use in this situation.

Sam