tags:

views:

2059

answers:

4

We are using NHibernate to manage our persistence in a complex modular windows forms application - but one thought keeps bothering me. We currently open a session on launch and open all objects through that session. I am worried that all loaded objects get loaded into the NHibernate session cache, so that they cant be garbage collected, and ultimately we will end up with the whole database in memory.

This never happens with web applications because web page requests (and even better Ajax requests) represent the perfect short lived transaction so a session can be opened and closed to handle each request.

However if I load an tree of objects in my forms application and put then into a navigation pane on the screen they may stay their for the life of the application - and at any point the user may click on them, resulting in our code needing to navigate the object relationships to other objects (which only works within an NHibernate session).

What do StackOverflow readers do to keep the benefits of NHibernate without the issues I describe?

A: 

I can see a couple of alternatives:

  1. Eager-load the object tree (which, from what I can gather from the documentation is the default)
  2. Detach the objects, intercept the "click" event, and load the data from the database then, with a new session. This one forces you to take care of collections by yourself, instead of relying on nhibernate, which may fall outside of the scope of the question (which asks for the benefits of NHibernate, one of which is collection management)
Bruno Lopes
+2  A: 

Ayende and company usually recommend using a session per "conversation". This usually makes the session lifetime last for very short operations, so it behaves more like a web app.

For your tree case, you can use Bruno's solution #2 just fine. The objects can be lazily mapped. Then, every time you need to access a child collection, you start a conversation and reconnect the parent via ISession.Lock. Then when the databinding is done, close that session. Not too much overhead to maintain, just a few lines of code in any form that needs to carry a conversation; you can extend Form and the controls you're using to do this automatically if you're feeling sassy.

The tricky part, then, is concurrent edits from different sessions. Let's not go there!

Dan Fitch
Here is an article with a nice sample of how to implement the session per conversation in a desktop style application: http://msdn.microsoft.com/en-us/magazine/ee819139.aspx
David Lynch
+2  A: 

I open a session when I need one, and I'll close it when I know that I won't need it anymore.

More specifically, for instance, if I have a form which lets me edit Customer information for instance, I'll open a session when the form gets instantiated, and I'll close the Session when the form is closed. When I have 2 instances of that form open, I also have 2 session open.

Frederik Gheysels
+1  A: 

You can take a look to my posts on how to use uNHAddins to work with session per conversation in a Windows Forms application (uNHAddins is a project with some additionsns to NHibernate led by Fabio Maulo, current NH Lead)

The first post is this

http://gustavoringel.blogspot.com/2009/02/unhaddins-persistence-conversation-part.html

From there you have links to uNHAddins trunk.

Tavo