tags:

views:

371

answers:

2

Let's say I got a simple view that displays a Product Name and whether it has been discontinued. I am pulling the data out of Northwind database. I am using a simple Model View Pattern and a DAO Pattern with NHibernate. When the Form loads I have my UI with a Load Button and a Save button. If I hit the Load button than in my code behind I simply pass the call to my Presenter to load the data. The preseneter calls the DAO to get the data and populate the view with the data. Than I hit the Save button. again my code behind passes the call off to the presenter. The presenter needs to have the session object that was created on Load to do optimistic concurrency, change tracking etc...

So my question is where do i create my ISession object so that it can do change tracking and optimistic concurrency?

A: 

HTTP is stateless. Your unit of work exists on the server-side only. As for clicking 'Load' then your UOW is simply retrieve the record and map to your view model. 'Save' and unit of work starts when you hit the server - rather than being over the course of the load, edit in browser, and then back to server.

Implementation wise you shouldnt keep the ISession in memory (in your case ASP.Net session object), it a sure fast way to exhausting memory and unmanaged ado.net resources. There are various UOW examples some people choose to associate a ISession with the HTTP Context at begin_request and dispose on end_request, you can of course be more granular, but in all cases it never exists further than that.

In a simplictic system, on hitting the 'Save' you will need to pull the Product out of the database using an ID (hidden field or what not), set the properties from the Request.Form, and then update in the database.

As for concurrency. If you record the timestamp or an increment version in a hidden field

<input type="hidden" name="version" value="12"/>

Then when you hit Save, you pull the Product out of the database, check that the version number in the Request.Form matches and then save, if not return to the user that the data has changed since last retrieved, would you like to proceed? NHibernate has timestamp/version fields so the comparison is done when you actually hit the DB basically a where clause on the Update, so in this instance it even accounts for changes to very moment you commit.

There are more elaborate and sophisticated ways but generally you can't/shouldn't be sticking ISession in your asp.net Session object.

mattcodes
not thinking about web applications. I am wondering about winform appplications. sorry for the fact that I did not specify that in my question
codemnky
My bad, create your ISession at application startup, close on finish. Presumably your DB ops are not threaded this should be fine. Use a singleton manager if you dare
mattcodes
While I can attest to the fact that creating one session for the lifetime of the application works, it is not recommended by most nHibernate 'experts'. I believe there are memory usage issue related to caching and potential problems if exceptions are thrown or you need to rollback a transaction.
Chris Nicola
A: 

Since you are using MVP I will assume this is a desktop app and not a web application. UnitOfWork is a good pattern for this as is the "Persistent Conversation". Ayende recently wrote an excellent article on building a desktop application with nhibernate so I would definitely take a look at that.

Chris Nicola