views:

1659

answers:

2

I am having a heck of a time trying to figure out my session management woes in NHibernate. I am assuming that a lot of my trouble is due to lack of knowledge of IoC and AOP concepts; at least that is what I am thinking by where Fabio Maulo keeps directing me.

Anyways, my problem is that I have a win forms application that is making "get" calls and binding the result to a grid. After binding the user may perform some kind of "write" action and those result in the session being closed after the write in an attempt to use the session per use concept. Then the user may scroll through the grid which causes the lazy loading to kick off and now the session has been closed and I get an exception.

I do not want to make my view cognizant of my sessions, I don't want to send off a KillAllSessions when the user closes the form. Plus a user may have multiple forms open at any given time further compounding the issues associated with that method. I essentially want all of this to work "behind the scenes".

So my idea thus far is to intercept the lazy loading call and check to see if the session is open and if not re-open it, get the information then re-close it. However, as far as I can tell, which isn't much, this is essentially how the lazy loading works anyways. It is intercepted by the proxy factory (NHibernate.Bytecode.Castle) and then retrieves the data using the session. So I need to actually intercept that call then pass it on to the original intended intercept after re-opening the session. So that is my idea.

My question is essentially first of all is this even the right way to go about this? Second if it is I don't even know where to start. I have never done any intercepting of method calls, I knew of it in theory but not in practice. I know there are libraries out there that do this kind of thing such as Rhino Commons, but I want to take this opportunity to learn and become a better programmer. I am trying to understand AOP and Context Bound Objects but currently I am not grokking it. Could some of you folks please help a guy out?

+3  A: 

I can think of a few options:

Option 1: Keep the original ISession open while the user interacts with the data and commit all the changes at once when the user is done. This means that you may have a large number of uncommitted changes in memory and other users will not see pending changes.

Option 2: Split the operations into two units of work (UOW). UOW1 only does reads and is responsible for populating the list. The ISession associated with UOW1 remains active to allow for lazy loading, such as in a drill-down scenario. UOW2 is a new short-lived ISession that is created for user edits. When an edit commits, the original object is evicted from UOW1 and UOW1 fetches a new copy from the database.

Option 3: Recreate the list after every edit commits. This is the easiest solution and might be suitable for small data sets.

Jamie Ide
James, thank you for your response, I have a question though. With option 1 and 2 how would I close the session after the "gets" without the view sending a Kill message to the Session Manager telling it the user is closing the application or the form?
joshlrogers
I don't know enough about your architecture to comment. However, it sounds like the unit of work boundary would be when the form is closed. I think it's much better to manage the session lifetime locally than to have a global session manager that has responsibilities beyond creating new sessions.
Jamie Ide
+2  A: 

I am working on a similar application. I am using one session that I keep open.

Whenever I write to the database I use begin/commit transaction which does not close the underlying session. the database connection is only open by NHibernate while the transaction is in progress.

Is there a reason you need to close the session while the user is actively using the form?

Can you provide more details on what you are using to manage your session, repository pattern, ... etc?

Maggie
Because I am trying to keep my view from being cognizant of my DAL or any of its workings. My session was being managed by a singleton pattern before I happened upon this issue.
joshlrogers
I create my session/repositories via StructureMap and only the model uses them. My view is unaware of persistence.
Maggie