Hibernate Opensession() VS Getcurrentsession()

Hibernate openSession() vs getCurrentSession()

As explained in this forum post, 1 and 2 are related. If you set hibernate.current_session_context_class to thread and then implement something like a servlet filter that opens the session - then you can access that session anywhere else by using the SessionFactory.getCurrentSession().

SessionFactory.openSession() always opens a new session that you have to close once you are done with the operations. SessionFactory.getCurrentSession() returns a session bound to a context - you don't need to close this.

If you are using Spring or EJBs to manage transactions you can configure them to open / close sessions along with the transactions.

You should never use one session per web app - session is not a thread safe object - cannot be shared by multiple threads. You should always use "one session per request" or "one session per transaction"

When to use OpenSession() and GetCurrentSession()

openSession--> If we use this method, we need to flush() and close() the session. It does not flush and close() automatically. We can use this method when we decided to manage the Session our self.

getCurrentSession--> A session is opened whenever getCurrentSession() is called for the first time and closed when the transaction ends. This creates a brand new session if one does not exist or uses an existing one if one already exists. It automatically configured with both auto-flush and auto-close attributes as true means Session will be automatically flushed and closed.
We can use getCurrentSession() method when our transaction runs long time.

getCurrentSession is usually sufficient. openSession provides and facilitates a greater level of management of where the session is stored and managed. It's certainly an advanced option, but one that does indeed fit the need of very clever developers who are doing some nifty things with the session.

Note: Using getCurrentSession() to create the session will automatically terminate at a commit or rollback, and using openSession() to create the session will require manual termination

Hibernate OpenSession() Vs GetCurrentSession()

CurrentSessionContext only tells NHibernate which implementation of session context it should use. There are multiple available depending on type of application you are writing. Once it is configured, you then need to bind every session object that you create to the session context. Following code explains how to do that

public class SessionManager
{
private static readonly ISessionFactory sessionFactory;

static SessionManager()
{
sessionFactory = new DatabaseConfiguration().BuildSessionFactory();
}

public static ISession GetCurrentSession()
{
if (CurrentSessionContext.HasBind(sessionFactory))
{
return sessionFactory.GetCurrentSession();
}

var session = sessionFactory.OpenSession();
CurrentSessionContext.Bind(session);
return session;
}

public static void Unbind()
{
CurrentSessionContext.Unbind(sessionFactory);
}
}

Now, whenever you need a session object, you can call SessionManager.GetCurrentSession and it would internally do the following

  1. Check if there is an existing session object bound to the context, if yes, return the current session from the session factory because that is the one bound to the context
  2. If not, then open a new session, bind it to the CurrentSessionContext and return the session object

Notice that there is an Unbind method on SessionManager that you can use to unbind a session object.

Now, about the warning more than one session per request. This warning is clearly telling you that you are using more than one session per request (if you are using it in the context of a web application). A popular approach to counter this warning is to use a "Session per request" pattern. In this pattern, for every incoming request, you create a new session object as the request hits your code, use that session object through out the request processing and dispose the session object when request leaves your code. The following code can be added to global.asax.cs file of an ASP.NET MVC application to get "session per request"

public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}

protected void Application_BeginRequest(object sender, EventArgs e)
{
var session = SessionManager.GetCurrentSession();
}

protected void Application_EndRequest(object sender, EventArgs e)
{
var session = SessionManager.GetCurrentSession();
session.Close();
session.Dispose();
}
}

How does getCurrentSession work without openSession?

The javadoc says:

Obtains the current session. The definition of what exactly "current" means controlled by the CurrentSessionContext impl configured for use.

You're using a ThreadLocalSessionContext. Its javadoc says:

A CurrentSessionContext impl which scopes the notion of current session by the current thread of execution. [...] In the interest of usability, it was decided to have this default impl actually generate a session upon first request and then clean it up after the Transaction associated with that session is committed/rolled-back.

You shouldn't close sessions obtained that way. Instead, you should commit the transaction that you have begun. This will close the session, as the documentation says.

getCurrentSession() vs openSession()

Found the solution, with genericDAO it gets the current session which needs to be explicitly open using openSession(), while getCurrentSession() just attaches it to the current session. According to the author

GenericDAO makes the assumption that you will be handling transactions
externally to the DAO

Hibernate: sessionFactory.openSession() VS sessionFactory.getCurrentSession()

Answer to the first question :
you should have a session per user connected. For example, if you are in a servlet context, you can have a servlet filter to call sessionFactory.openSession() per servlet thread.

Answer to the second question :
performance and optimisation is not a feeling. If you feel hibernate slow, measure it and try to know why. You have to measure where it slows. You can also try both solutions with a simple example and know where you feel more comfortable.

Difference b/w Hibernate's Sessionfactory.getCurrentSession() and SessionFactory.openSession()

A session is opened whenever sf.getCurrentSession() is called for the first time. This creates a brand new session if one does not exist or uses an existing one if one already exists.

In Tomcat this associates a session with a thread which is created using the underlying ThreadLocal object. But since Tomcat uses thread pooling it is entirely possible that a request may receive a thread with a session already associated with it, thus introducing the possibility of not even creating a brand new session. Another thing is that The Session that you obtained with sf.getCurrentSession() is flushed and closed automatically.

The method sf.openSession() on the other hand creates a new session but does not attempt to associate it with a thread. But remember sf.openSession() introduces another hitch in that it expects users to handle the closing and flushing of sessions themselves, instead of letting Hibernate do it automatically for us.

sf.getCurrentSession() is usually sufficient. sf.openSession() provides and facilitates a greater level of management of where the session is stored and managed. It's certainly an advanced option.



Related Topics



Leave a reply



Submit