XSockets.Net - how to manage NHibernate Session Context - nhibernate

I wonder what is the best way to manage NHibernate Session Context
when using NH data layer from Xsockets controller.
Particularly I refer to self hosted winservice/console application or Azure worker role,
where HTTPContext is not available.
Of course there is always an option to create and dispose session per call, but that means a performance hit, so better reuse sessions in some way.
My controller provides API for CRUD operations in underlying NH repository and is pushing updates to relevant subscribers when certain records are updated in DB.
Your ideas appreciated :)

I'm using StructureMap to handle dependencies and create a NestedContainer to handle session per request. Don't have to mess with CurrentSessionContext or HttpContext anymore for storing session.
http://structuremap.github.io/the-container/nested-containers/
You could even just create a middleware UnitOfWork if you are using OWIN with WebAPI.

Since XSockets has state is will be bad for your database if you open the connection in the OnOpen event since the connection will remain open as long as the socket is open. Best is to use the repository only in the methods calling the CRUD operations as briefly as possible.
To get the instance of your repository should not be a bottleneck in this case.
I will be happy to review any code you might have.
Regards
Uffe

Related

Is there a way to access the current Nhibernate session from anywhere?

I have some legacy code that used to open its own Sqlconnection. And I would now like to use the SqlConnection Nhibernate creates.
But I'd rather avoid to change the code a lot (DI, adding loads of settings, ...), so, Is there a simple (convienent) way to get the current Nhibernate session?
No. What is current NHibernate session anyway?
In a web application, each http request must work with its specific NHibernate session(s).
In a desktop application, each screen will probably use one session for each of their actions.
The NHibernate session is not supposed to be used as a singleton.
You should probably use your session factory to open a new NHibernate session in your legacy code then use its CreateSQLQuery method. Your session factory should usually have a singleton lifetime.
If you bound your NHibernate sessions to some context meaningful for your application (such as the HttpContext, CallContext), you may instead get it from there. Beware of cases which may cause contexts losses (async/await configured for not restoring context, asp.net thread agility (do not cause HttpContext losses but CallContext losses), ...).

Castle Windsor Interceptor and Unit Of Work

Is Castle Windsor's Inteceptor mechanism considered to be a good/effective way of implementing the Unit of Work pattern?
My project involves Castle Windsor, the NHibernate Facility and of course NHibernate - all used in self-hosted WCF services.
Each service method normally requests from the Windsor container an instance of a helper class into which the WCF call is delegated. The helper class has an ISessionManager constructor argument which Windsor resolves via the NHibernate Facility.
The trouble is, the helper class is doing too much work. It has both logic and data access intermingled which means its difficult (virtually impossible) to test and difficult to read.
What I want is to re-arrange responsibilities
I don't want the WCF helper to know anything about transactions or sessions, so no ISessionManager constructor arg, no references to transactions and no ISession.
In order for the WCF helper to do data access, its going to have to rely on a new helper, dare I call it a DAO? or God forbid a repository, on which will be methods for fetching, querying, and possibly saving domain objects.
The problem with returning NHibernate proxied objects from a DAO is that if the session is closed before the entity is returned, any subsequent attempt to access collections on the domain object from the client code will result in an exception as the session is no longer there to be used to lazily fetch the required data. It's obvious really, but everyone new to NHibernate must hit this issue.
So if DAOs and Repos cant close the session, what does?
What I need is one NHibernate session per WCF service operation call, where several DAOs or Respositories can call OpenSession as much as they like, but they all get the same session, and ideally, any attempt to dispose the session would be ignored unless its the last Dispose. Not sure about the last bit, but maybe DAOs and repos just call ISessionManager.OpenSession and leave it to something else to flush and dispose the session.
I thought maybe I could use an interceptor which takes an ISessionManager, opens a session and starts a transaction, forwards the invocation, then if no exception occurs, commits the transaction and disposes the session, otherwise rolls back the transaction if any exception occurs.
Any thoughts?
So if DAOs and Repos cant close the
session, what does?session, what does?
Services own units of work, not DAOs. They demark units of work.
Spring manages transactions using AOP, so interceptors sound like a good bet for transaction management to me.
As far as sessions go, those are UI concepts, so it ought to be the web or desktop UI controller that opens the session, marshals services to fulfill use cases, and closes the session when it's complete.
Castle.Service.Transactions also ties well together with the rest of the castle stack and allow you to use AOP to handle transactions.
Have a look at v3!
https://github.com/haf/Castle.Services.Transaction
And the wiki there!
I also created a new NHibernate Facility:
https://github.com/haf/Castle.Facilities.NHibernate/wiki/NHibernate-Facility---Quick-Start

nhibernate and sessions, please clarify

I am building a web application, and whenever I make a database call I need a session.
I understand creating a session object is very expensive.
I am following the repository pattern here: http://web.archive.org/web/20110503184234/http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/10/08/the-repository-pattern.aspx
He uses something called a UnitOfWork to get the session.
For a web application, shouldn't I be storing the Session in Request.Items collection? So its only created once per request?
Do I really need UofW?
The session IS the unit of work - its basically used to store changes until you flush them to the db. Save a static session factory at startup, and use that to create one session per web request - Request.Items seems a valid place to put the session.
The repository pattern is a wrapper over the unit of work. The repository pattern differs from the UoW pattern in that repo.Save(obj) should save the obj to the db straight away, while the UoW waits for a flush.
My advice would be to skip the repository pattern and use the ISession directly (see http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx)
In the case of NHibernate the key class is the SessionFactory, which SessionProvider is taking care of for you (if you implement it like that). Keep the SessionFactory alive, and it handles the sessions for you.
I've also seem people save the SessionFactory in their IoC.
Use this to manage your sessions:
HybridSessionBuilder
It manages and gives you access to a single session that's used across the entire application.

Where is the session located ? in client browser or at the server side ? and why it is used in hibernate?

I know that the session is used for the database in Hibernate, but what is the task of the session in database?
Does anyone know about this?
Update:
Apologies, my links are to Java APIs (must have missed the nhibernate tag). Regardless, there will be more than one type of session for .NET also.
There will typically be more than one type of session:
The HttpSession is a server-side object:
Provides a way to identify a user
across more than one page request or
visit to a Web site and to store
information about that user.
The hibernate Session is also a server-side object:
The lifecycle of a Session is bounded
by the beginning and end of a logical
transaction. (Long transactions might
span several database transactions.)
The main function of the Session is to
offer create, read and delete
operations for instances of mapped
entity classes.
The session is server side, if by server side you mean as in the web application or client/server application sense.
It is an implementation of the Unit of Work pattern, and does stuff like keeping track of which entities that have been changed, caching of entities and making sure that a specific entity is represented by only one actual instance in the scope of the session.
The NHibernate docs describe ISession like this:
A single-threaded, short-lived object
representing a conversation between
the application and the persistent
store. Wraps an ADO.NET connection.
Factory for ITransaction. Holds a
mandatory (first-level) cache of
persistent objects, used when
navigating the object graph or looking
up objects by identifier.

NHibernate Transactions in Open View per Session - suggested practices?

Cleaning up some transactional logic and wondered how other people were handling it.
Ayende's recommendation seems to be to handle transactions at the service boundary. This is a ASP.NET web app though, so it hasn't got a clear cut service boundary, at least not right now.
What do people do?
Create a single transaction per request in a HttpModule and handle commit on EndRequest, rollback on Error?
Create transactions in the actual "services" in the application and handle it multiple places?
Something else?
You can use a IoC Container for your service layer and the container can manage the transaction and the Nibenrate Session.
Your WebApp Controller => call (A) Service Layer => call (B) one or several DAO methods /operations.
The IoC container like Spring.NET will manage te TX scope, by example at (A) and will provide a Session to your DAO in (B). The commit (or rollback) will be handled at the end of the service layer call.
Most people use a session-per-request strategy as stated in your first bullet point. However, I don't believe that the transaction needs to be committed on EndRequest. In many web pages it would be easier to commit the transaction based on user action (e.g. clicking submit) and let EndRequest just handle disposing the ISession.
As far as I can tell, there's no need to create an HttpModule as the same functionality can be created in global.asax: http://forum.hibernate.org/viewtopic.php?t=993041.