Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate Session closed problem!

The function below is the actionListener for a button I have in my web application, I am deleting the old chosen rows from a table in a database and inserting the new ones to the database.

public void getSelectedExemptionItems(ActionEvent ae) {
        Session hibernateSession;
        Session hibernate2Session;
        selectedExemptions = new ArrayList<ExemptionBean>();
        for (ExemptionBean eBean : exemBean) { // iterating over the list of ExemptionBean class
            if (selectedExemptionIDs.get(eBean.getExemptionID()).booleanValue()) {
                selectedExemptions.add(eBean); // adding every ExemptionBean that is selected.
            }
        }
        // getting importane session variables
        SessionBean1 theSessionBean = (SessionBean1) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("SessionBean1");
        JAdmApplication admApplication = theSessionBean.getAdmApplication();
        long admAppID = admApplication.getJAdmApplicationId();
//        ArrayList<JAdmAppExemption> admAppExemption = (ArrayList<JAdmAppExemption>)theSessionBean.getAdmAppExemption();

        JAdmAppExemption admAppExem = new JAdmAppExemption();

        // try catch : delete all previously chosen exemptions from database by logged-in user.
        try {
            hibernateSession = HibernateUtil.getAdmSessionFactory().getCurrentSession();
            Transaction t = hibernateSession.beginTransaction();
            t.begin();
            String sequel = "DELETE FROM JAdmAppExemption WHERE createdby = ?";
            Query q = hibernateSession.createQuery(sequel);
            q.setParameter(0, theSessionBean.getPortalUserId());

        } catch (Exception e){
            System.out.println("Row could not be deledted from database!!");
        }

//         adding all selected exemptions to the database

        for (ExemptionBean e : selectedExemptions) {
            admAppExem.setAdClientId(1000001);
            admAppExem.setAdOrgId(1000001);
            admAppExem.setCreated(getTimestamp());
            admAppExem.setCreatedby(theSessionBean.getPortalUserId());
            admAppExem.setIsactive('Y');
            admAppExem.setJAdmAppExemptionId(getJAdmAppExemptionIdSequence());
            admAppExem.setJAdmApplicationId(admAppID);
            admAppExem.setJAdmExemptionId(e.getExemptionID());
            admAppExem.setUpdated(getTimestamp());
            admAppExem.setUpdatedby(theSessionBean.getPortalUserId());

            hibernate2Session = HibernateUtil.getAdmSessionFactory().getCurrentSession(); // session is opened here!
            Transaction tx = hibernate2Session.beginTransaction();
            tx.begin();
            try {
                hibernate2Session.beginTransaction();
                hibernate2Session.save(admAppExem); // is it save or saveOrUpdate??
                hibernate2Session.getTransaction().commit();
                updateJAdmAppExemptionIdSequence();

            } catch (Throwable ex){
                if (hibernate2Session.getTransaction().isActive()) {
                    hibernate2Session.getTransaction().rollback();
                }
                ex.printStackTrace();
            }
        }
    }

I keep getting an exception : Session is closed !! can someone please explain how sessions are closed in hibernate (automatically??) and how to work with them..

here is the detailed stack trace of the exception:

javax.faces.FacesException: org.hibernate.SessionException: Session is closed!
        at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:90)
        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
        at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
        at com.icesoft.faces.webapp.http.core.JsfLifecycleExecutor.apply(JsfLifecycleExecutor.java:18)
        at com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.renderCycle(ReceiveSendUpdates.java:132)
        at com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.service(ReceiveSendUpdates.java:74)
        at com.icesoft.faces.webapp.http.core.RequestVerifier.service(RequestVerifier.java:31)
        at com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:24)
        at com.icesoft.faces.webapp.http.servlet.BasicAdaptingServlet.service(BasicAdaptingServlet.java:16)
        at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
        at com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:53)
        at com.icesoft.faces.webapp.http.servlet.SessionVerifier.service(SessionVerifier.java:26)
        at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
        at com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:131)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at com.icesoft.faces.webapp.xmlhttp.BlockingServlet.service(BlockingServlet.java:56)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
        at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:857)
        at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:565)
        at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1509)
        at java.lang.Thread.run(Thread.java:619)
Caused by: javax.faces.el.EvaluationException: org.hibernate.SessionException: Session is closed!
        at com.sun.faces.application.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
        at javax.faces.component.UICommand.broadcast(UICommand.java:380)
        at com.icesoft.faces.component.panelseries.UISeries$RowEvent.broadcast(UISeries.java:617)
        at com.icesoft.faces.component.panelseries.UISeries.broadcast(UISeries.java:285)
        at com.icesoft.faces.component.paneltabset.PanelTabSet.broadcast(PanelTabSet.java:320)
        at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:475)
        at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:756)
        at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
        ... 27 more
Caused by: org.hibernate.SessionException: Session is closed!
        at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:49)
        at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1319)
        at sun.reflect.GeneratedMethodAccessor2480.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:301)
        at $Proxy233.beginTransaction(Unknown Source)
        at univportal.AdmissionApplication.Application.getSelectedExemptionItems(Application.java:1595)
        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:597)
        at org.apache.el.parser.AstValue.invoke(AstValue.java:172)
        at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
        at com.sun.faces.application.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
        ... 34 more

Thanks,

like image 794
Saher Ahwal Avatar asked Dec 29 '22 12:12

Saher Ahwal


2 Answers

Here is a concise answer I found to this question here if anyone encounters this problem in Hibernate. Apparently it is simple!

using managed sessions in hibernate to ease unit testing 06nov06

If you’ve ever tried to reuse a session in Hibernate you may have come across this exception…

org.hibernate.SessionException: Session is closed!
   at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:49)
   at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1319)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:301)
   at $Proxy0.beginTransaction(Unknown Source)
   ....

The reason for this is that Hibernate is using thread managed sessions. With this type of session management Hibernate manages the session for you. When you first attempt to use a session Hibernate will create one and attach it to your local thread. When you commit the transaction in the session Hibernate will automatically close the session meaning it can’t be reused.

To get around this problem the best option is to use managed sessions. With managed sessions you’re in full control of creating, flushing, commiting, and closing sessions. Here’s how.

In your hibernate.cfg.xml change the property current_session_context_class to managed.

To create a session and start a transaction in that session do this…

org.hibernate.classic.Session session = HibernateUtil.getSessionFactory().openSession();
   session.setFlushMode(FlushMode.MANUAL);
   ManagedSessionContext.bind(session);
   session.beginTransaction();

To commit a transaction in the session do this…

ManagedSessionContext.unbind(HibernateUtil.getSessionFactory());
   session.flush();
   session.getTransaction().commit();
   session.close();

To use this code in unit tests I created this base unit test class that all my unit tests extend. Whenever I want to create a new session or transaction I call the method createNewSessionAndTransaction(). To commit the session’s transaction I call the method commitTransaction().

import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.context.ManagedSessionContext;
import util.HibernateUtil;
import junit.framework.TestCase;

/**
 * Abstract unit test with helper methods for managed session control
 */
public abstract class ManagedSessionUnitTest extends TestCase {

   /**
    * Create a new Session.
    *
    * For this method to work, the application managed session strategy has to
    * be enabled. This basically means that the life of a session is controlled
    * by you and and not by Hibernate.
    *
    * To enable the application managed session strategy set the property
    * hibernate.current_session_context_class to "managed".
    *
    * Within this method we create a new session and set the flush mode to
    * MANUAL. This ensures that we have full control over when the session is
    * flushed to the database.
    */
   protected org.hibernate.Session createNewSession() {
      org.hibernate.classic.Session session = HibernateUtil.getSessionFactory().openSession();
      session.setFlushMode(FlushMode.MANUAL);
      ManagedSessionContext.bind(session);
      return (org.hibernate.Session) session;
   }

   /**
    * Start a new Transaction in the given session
    * @param session The session to create the transaction in
    */
   protected void startNewTransaction(Session session) {
      session.beginTransaction();
   }

   /**
    * Shortcut method that creates a new session and begins a transaction in it
    * @return A new session with a transaction started
    */
   protected org.hibernate.Session createNewSessionAndTransaction() {
      Session session = createNewSession();
      startNewTransaction(session);
      return session;
   }

   /**
    * Commit the transaction within the given session. This method unbinds
    * the session from the session context (ManagedSessionContext), flushes
    * the session, commmits the session and then closes the session
    * @param session The session with the transaction to commit
    */
   protected void commitTransaction(Session session) {
      ManagedSessionContext.unbind(HibernateUtil.getSessionFactory());
      session.flush();
      session.getTransaction().commit();
      session.close();
   }

}
like image 103
Saher Ahwal Avatar answered Jan 13 '23 14:01

Saher Ahwal


You're using lazy fetching in a session scoped managed bean while the Hibernate session is apparently configured to be request based.

Long story short: Understanding Lazy Fetching in Hibernate.

like image 43
BalusC Avatar answered Jan 13 '23 12:01

BalusC