-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: HibernateException: Session is closed
PostPosted: Sat Feb 19, 2005 3:13 am 
Newbie

Joined: Thu Dec 02, 2004 2:13 pm
Posts: 10
Hello,

My problem is that when I attempt to commit a transaction I get an HibernateException which states that my session has been closed. I'm using HibernateUtil from the "Hibernate in Action" book. I set a breakpoint in the HibernateUtil.commitTransaction() method and I can see that the tx (Transactions) session variables closed status is set to true. The session variable being used to perform database operations closed status is false.

What is closing the session for the tx object??


Hibernate version:
2.1.7

Mapping documents:

Code between sessionFactory.openSession() and session.close():
Code:
         Product product =
             (Product)session.getAttribute(ProductAction.PRODUCT);
         if(product != null) {
            try {
               // NOTE: creating a new ProductDAO() calls
               // HibernateUtil.beginTransaction();
               ProductDAO productDao = new ProductDAO();
               Specifications spec = product.getSpecification(specId);
               spec.setName(specsForm.getName());
               spec.setDetail(specsForm.getDetail());
               product.addSpecification(spec);
               productDao.makePersistent(product);
               HibernateUtil.commitTransaction();
            } finally {
               HibernateUtil.closeSession();
            }
        }


makePersistent() method of ProductDAO class

Code:
   public void makePersistent(Product product)
         throws InfrastructureException {

      try {
         HibernateUtil.getSession().saveOrUpdate(product);
      } catch (HibernateException ex) {
         throw new InfrastructureException(ex);
      }
   }


Full stack trace of any exception that occurs:

net.sf.hibernate.HibernateException: Session is closed
at net.sf.hibernate.impl.SessionImpl.connection(SessionImpl.java:3327)
at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:63)
at com.myProject.util.HibernateUtil.commitTransaction(HibernateUtil.java:187)
at com.myProject.struts.action.SpecificationsAction.update(SpecificationsAction.java:139)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:276)
at org.apache.struts.actions.LookupDispatchAction.execute(LookupDispatchAction.java:162)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:226)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:415)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:825)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:731)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:526)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

Name and version of the database you are using:

MySQL 4.0

Thanks,

c.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 19, 2005 9:56 am 
Newbie

Joined: Sun Sep 21, 2003 3:04 pm
Posts: 11
Location: Germany
Code:
public void makePersistent(Product product)
         throws InfrastructureException {
Session hbmSession;
Transaction transaction;
      try {
         hbmSession = HibernateUtil.getSession();
         transaction = hbmSession.beginTransaction();
         hbmSession.saveOrUpdate(product)
         transaction.commit();
      } catch (HibernateException ex) {
         if (transaction != null)
           transaction.rollback();
         throw new InfrastructureException(ex);
      }
       finally {
          if (hbmSession !)= null)
              HibernateUtils.closeSession();
        }
       
   }

_________________
_______________________
With best regards
S.Homburg
21220 Seevetal / GERMANY


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 25, 2005 5:48 am 
Newbie

Joined: Fri Feb 18, 2005 2:38 am
Posts: 4
I am not able to get you the link, but I have the text and this resolved my problem I had with session is closed

Good luck


Like many people in this forum, I have had problems with getting "Session is closed" errors. I saw a number of solutions, but none worked for me.

However, I have found a way to eliminate this problem.

The problem is that the createSession() method only creates one session per thread, but the closeSession() method always closes that session. As a result you CANNOT keep a reference to one session if you then call ANY method that calls closeSession() anywhere. The only way this can work is if you are able to somehow are able to ensure that you never call a method without passing the current session to it. I find that pretty unlikely, but apparently many people do it that way. Anyway, thankfully there's an easy way to fix it.

First, go into the Hibernate Synchronizer preferences and change the "BaseRootDAOHelperMethods" snippet in the following ways:
1. rename the closeSession() method to be closeSessionForReal().
2. Add the following definition of closeSession():
public void closeSession () throws HibernateException {}


Now, at the outermost part of each thread (each servlet or action or whatever), do the following:

Code:

Session session = null;
Transaction tx = null;
try {
session = _RootDAO.createSession();
tx = session.beginTransaction();

// .. do stuff here. You can pass the session around, but you don't need to

tx.commit();
} catch(Throwable e) {
if(tx!=null && session!=null && session.isOpen())
tx.rollback();
// log error or whatever
// ...
} finally {
// Here, UserObjProfDAO is any DAO class in your application. It doesn't matter which one.
UserObjProfDAO.getInstance().closeSessionForReal();
}


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 25, 2005 6:16 am 
Newbie

Joined: Thu Feb 24, 2005 5:34 am
Posts: 4
Location: Aalborg, Denmark
This solution startles me a little...

You solve the problem by creating a new method that does the actual seesion closing?

Then what is the intend of the methods you have that invoke closeSession()? If they don't mean to really close the session then why do the invoke it?

No offence - but to me this seems a workaround to some design flaw with the session control in the first place. One must consider the demarcation of sessions and not invoke close unless that is really what is intended.

Maybe implementing some kind of Facade pattern where the facade calls the involved DAOs and each method of the facade handles the sessions. The DAOs behind then never manually doing session demarcation might be one way to solve you problem. But that was just my thought when I read the post :-)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 19, 2005 6:16 pm 
Newbie

Joined: Tue Jul 19, 2005 6:08 pm
Posts: 1
Try changing the HibernateSessionFactroy java file. I had a similar error which was corrected by changing that file. This code worked for me:

public static Session currentSession() throws HibernateException {
Session session = (Session) threadLocal.get();
/*
* [laliluna] 20.12.2004
* we want to use the standard session.close() method and not the closeSession() from
* this class.
* For this we need the following line of code.
*/
if (session != null && !session.isOpen()) session = null;
if (session == null) {
if (sessionFactory == null) {
try {
cfg.configure(CONFIG_FILE_LOCATION);
sessionFactory = cfg.buildSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating HibernateSessionFactory %%%%");
e.printStackTrace();
}
}
session = sessionFactory.openSession();
threadLocal.set(session);
}
return session;
}


Top
 Profile  
 
 Post subject: No ThreadLocal variable for the Transaction
PostPosted: Tue Jun 20, 2006 7:11 pm 
Newbie

Joined: Tue Jun 20, 2006 7:04 pm
Posts: 2
If you have made a HibernateUtil class -> don't store the Transaction in a ThreadLocal variable.

Just store the Session in a ThreadLocal variabel. And use this Session to get and start the Transaction. So you are sure that you are always using the right Transaction for the current Session.

Best Regards,

Filip Rotsaert

SDR
Belgium


Top
 Profile  
 
 Post subject: No ThreadLocal variable for the Transaction
PostPosted: Tue Jun 20, 2006 7:12 pm 
Newbie

Joined: Tue Jun 20, 2006 7:04 pm
Posts: 2
If you have made a HibernateUtil class -> don't store the Transaction in a ThreadLocal variable.

Just store the Session in a ThreadLocal variabel. And use this Session to get and start the Transaction. So you are sure that you are always using the right Transaction for the current Session.


Code:
public static void beginTransaction() {
Session session = getSession();

Transaction t = session.getTransaction();

if (!t.isActive()) {
t.begin();
}

try {
if (t == null) {
t = getSession().beginTransaction();
}
} catch (HibernateException e) {
throw new InfrastructureException(e);
}
}



Best Regards,

Filip Rotsaert

SDR
Belgium


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.