Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getCurrentSession hibernate in web

I am writing a web based application with hibernate and jsp/servlet. I have read about the sessionFactory.getCurrentSession and sessionFactory.openSession methods. I know the basic difference between them (using getCurrentSession you don't have to close the connection and when you commit the transaction, your session will automatically close). According to the my understanding, we should opt for getCurrentSession and do it through session-per-request.

Let's consider the following scenario:

  1. Method A calls getCurrentSession and got the current session
  2. In Method A, a transaction is started using the session from step 1
  3. Method A calls Method B, which also has getCurrentSession and starts a transaction
  4. Method B commits its transaction
  5. Control returns to method A and it also commits the transaction

Now my questions are

  1. Will the session found in step 1 and step 3 will be the same session?
  2. If the answer for the question 1 is yes, then how would it handle the commit in step 4? Ideally it should close the session there itself and should throw an exception at step 5.
  3. If the answer for the question 1 is no, then how do you handle such a scenario?
like image 236
Aashutosh Avatar asked Sep 26 '10 13:09

Aashutosh


People also ask

What is getCurrentSession in Hibernate?

Hibernate SessionFactory getCurrentSession() method returns the session bound to the context. But for this to work, we need to configure it in hibernate configuration file like below. <property name="hibernate.current_session_context_class">thread</property>

What is the difference between getCurrentSession () and openSession ()?

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.

What is a SessionFactory () in Hibernate?

Most importantly, the SessionFactory in Hibernate is responsible for the creation of Session objects. The Hibernate Session provides methods such as save, delete and update, all of which are used to perform CRUD-based operations on the database to which the SessionFactory connects.

Is SessionFactory Singleton in Hibernate?

@DarkHorse SessionFactory is not Singleton , it is used as singleton , it is immutable docs.jboss.org/hibernate/orm/3.5/javadocs/org/hibernate/…


2 Answers

Will the session found in step 1 and step 3 will be the same session?

They should be the same, that's somehow part of the contract of getCurrentSession() and you'll get the Session bound to the thread as long as the unit of work has not been completed (i.e. a transaction has been committed or rolled back). Java Persistence with Hibernate puts it like this (p.481):

All the data-access code that calls getCurrentSession() on the global shared SessionFactory gets access to the same current Session — if it’s called in the same thread. The unit of work completes when the Transaction is committed (or rolled back). Hibernate also flushes and closes the current Session and its persistence context if you commit or roll back the transaction. The implication here is that a call to getCurrentSession() after commit or rollback produces a new Session and a fresh persistence context.

And you might also want to read what the javadoc of Session#beginTransaction() says.

If the answer for the question 1 is yes, then how would it handle the commit in step 4. Ideally it should close the session there itself and should give error at step 5.

Step 4 shouldn't be a problem, the Session will be flushed, the Transaction will be committed and the Session closed. But I expect step 5 to fail wih aTransactionException (that's my bet). But let me quote the javadoc of Transaction:

A transaction is associated with a Session and is usually instantiated by a call to Session.beginTransaction(). A single session might span multiple transactions since the notion of a session (a conversation between the application and the datastore) is of coarser granularity than the notion of a transaction. However, it is intended that there be at most one uncommitted Transaction associated with a particular Session at any time.

As underlined above, we are discussing around something that shouldn't happen (i.e. a design problem).

like image 183
Pascal Thivent Avatar answered Oct 18 '22 22:10

Pascal Thivent


I don't have an answer for your scenario because I would not implement it that way as it seems to be asking for trouble. Instead, I'd start the transaction in C, where C invokes A and B, and have C issue the commit. Skeletally:

public void c(...) {
    try {
       transaction.begin();
       a();
       b();
       transaction.commit();
    catch (Exception e) {
       transaction.rollback();
    }
}

So here, a() and b() do not commit or rollback - how do they know the entire business task has been completed? They could throw an exception or perhaps return a boolean to tell the caller that something is amiss and a rollback is needed.

like image 34
Tony Ennis Avatar answered Oct 18 '22 20:10

Tony Ennis