• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Is it a good idea to share a Session in hibernate ?

 
Raj Ohadi
Ranch Hand
Posts: 316
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am reading a book titled "Beginning Hibernate" byDave Minter.

They use a "DAO.java" as Base DAO. It has methods like "commit", "close", "rollback", "getSession", etc. Interestingly, it specifies

private static final ThreadLocal session = new ThreadLocal();

Then they created some "UserDAO", "ProductDAO" which extends "DAO" class. In each children DAO class, they call "getSession()" method defined in "DAO" class and use it. In its "rollback()" method it closes session.

Questions:

1. is it safe to use a "static" Session variable ? that means every client is using the same session once it's created. And if one client needs to call DAO's "rollback" method, basically it will close the session. If at this moment another client is still trying to use the session to commit, then the 2nd client will be unable to commit because session is closed by another client.

2. is it safe to use a singleton type Session in a clustered environement ?

3. will the problem be "fixed" if we make the session as a instance variable instead of a class variable ? But that means every client creates a new session. That may be too costly. So, what's the better way to handle session creation issue ?

4. Plus, I don't see that in the book, they close the session in each action method of "UserDAO" and "ProductDAO". They close the session at client level (in client code that calls UserDAO). Maybe it is because they want to keep using this session ? What's the standard DAO manner regarding closing a session ? shall we close it in each action method using "finally" ? Thats means we have to create a new session everytime we call a different action method.. Any thought ?

It's long. Thanks for attention.
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Raj,

Actually in that model, the session is not being shared among users. The big key is that ThreadLocal object. I highly recommend reading the javadocs for that class, and you will see that each client/user will get their own Session.

Because, yes it is not a good idea to share a Session, or keep a Session open for a really long time, especially if it is holding on to the Connection object. Sessions should be short and sweet, because the more objects you load into a Session the more memory it takes, and the more likely you will have a memory leak because your app would forget to evict those objects from the session.

Mark
 
Raj Ohadi
Ranch Hand
Posts: 316
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Mark. I just googled 'ThreadLocal' and I think I learnd something from it.. However, I still don't quite understand it --- It seems every client is using the "same" session instance but anything related to the client is held "within" its own "thread" ? Does this sound correct ? More importantly, if one client calls the "close()" method, does it mean it only close that local thread and does NOT close the session for other clients ? Again, here is the code from the book --

public class DAO {

private static final ThreadLocal session = new ThreadLocal();
private static final SEssionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

public static Session getSession() {
Session session = (Session)DAO.session.get();
if(session==null) { session = sessionFactory.openSession(); DAO.session.set(session);
} return session;
}

public static void close() { getSession().close(); DAO.session.set(null);
}

Another question is -- Doesn't "DAO.session.set(null)" kill other clients' session ??!!


One more ting I can't understand is -- In its UserDAo class

public class UserDAO extends DAO {

public User get(String name) {
try {
begin();
... some query code...;
return user;
} catch(HibernateException e) {rollback(); ..}
}

Question -- WOULDN"T it be nice if we ALWAYS add

finally { close();} in each method to close the session ? Can't understand why the book chooses to close the session from client side instead inside each DAO's method ?
 
Raj Ohadi
Ranch Hand
Posts: 316
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think I may have gotten some good guess on why they don't close the Session object when they use ThreadLocal. If it is closed, then next time when you run another method you need to create a new session; so if you need to run multiple methods together you can close it when all of them are done.

However, if you don't use Thread Local, even you don't close the session after one method, the next time when you call another method it is going to open a new session ANYWAY so it can not be thread safe anyway.

Using Thread Local, you can control when you want to keep the safe hibernate session for a given thread. But usually you let the client or action class close the hibernate session for you.

DO I understand this correctly , Mark ?
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic