I know that there has been written a lot about this topic, but somehow, I haven't found the 'sweet spot' concerning NHibernate Session Management in WinForms applications yet.
Some time ago, I've created a simple abstraction around the NHibernate ISession which would make it easier to use the ISession in my Winforms application.
Why do I want to clutter my presentation layer with NHibernate stuff, you ask ? Because Context is King.
The Repository has no notion of transactions, since the Repository doesn't know the context in where it's used.
Therefore, I like to start my Transaction in my WinForm app for instance, and pass the 'Transaction' to my repository, like this:
In the code above, the
UnitOfWorkclass is just a simple wrapper around the NHibernate ISession which allows me to start and commit or rollback a transaction, disconnect the ISession from the Database, etc... with a minimum amount of code.
The UnitOfWork class looks like this:
This approach also allows me to have multiple NHibernate ISessions opened in one application instance.
This approach also gives me full control about when to start a new UnitOfWork, and when to close a UnitOfWork.
I've been convinced that this was the way to go. Especially because I thought that you had to commit the changes you've made to an object using the same ISession as the ISession which you've used to retrieve the object if you want to avoid unnecessary
But, thanks to my collegue Thierry (who's starting to use NHibernate as well, and acted as some kind of catalysator to me so that I picked up my NHibernate quest again), it seems that my assumptions where not true:
I thought that, when you save an object to the datastore, using another ISession then the ISession you've used to retrieve the object, NHibernate would first perform a
SELECT query in order to find out whether an
INSERT or an
UPDATE statement should be executed.
This seems to be false if you do not use the 'assigned' generator class for your Id property.
So, now I'm in doubt:
- do I really need to be able to have concurrent ISessions in the same application instance ? Until now, I haven't needed it yet (so, yes, that makes it a YAGNI in fact).
- I haven't seen anyone on the net using a similar approach. I see that everyone uses some kind of 'SessionManager' like the one Billy McCafferty has written here, so this makes me doubt as well ...
This last point is also the reason for this blogpost: I'm in doubt :)
Using some kind of 'SessionManager' class allows me to do the transaction demarcation where ever I want as well. Next to that, I also do not have to pass my UnitOfWork to the repository, since the repository has access to the current Session via the SessionManager as well ...
I know that, maybe, I should just give it a try. However, I'd like to hear experiences and thoughts of other people who are using (N)Hibernate in a Rich Client environment as well.
How are you dealing with those (session management) issues ? What difficulties did you encounter ?
Note: another post of me regarding this subject can be found here
assumptions are the mother of all fuckups.