代码之家  ›  专栏  ›  技术社区  ›  Saher Ahwal

休眠会话已关闭问题!

  •  4
  • Saher Ahwal  · 技术社区  · 14 年前

    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();
                }
            }
        }
    

    我总是得到一个例外:会话已关闭!!有人能解释一下在hibernate中会话是如何关闭的(自动关闭的)以及如何使用它们吗。。

    以下是异常的详细堆栈跟踪:

    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
    

    谢谢,

    3 回复  |  直到 14 年前
        1
  •  4
  •   BalusC    14 年前
        2
  •  7
  •   lxcky    8 年前

    这是我对这个问题的一个简明答案 here 如果有人在Hibernate中遇到这个问题。显然很简单!

    在hibernate中使用托管会话简化单元测试2006年11月6日

    如果您曾经尝试在Hibernate中重用会话,您可能会遇到这个异常

    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)
       ....
    

    thread 托管会话。通过这种类型的会话管理,Hibernate为您管理会话。当您第一次尝试使用会话时,Hibernate将创建一个会话并将其附加到本地线程。当您在会话中提交事务时,Hibernate将自动关闭会话,这意味着它不能被重用。

    managed 会议。使用托管会话,您可以完全控制创建、刷新、提交和关闭会话。这就是方法。

    hibernate.cfg.xml 更改属性 current_session_context_class 管理 .

    创建 session 开始一个 transaction 在那里面 阶段 做这个

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

    commit 阶段 做这个

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

    为了在单元测试中使用这些代码,我创建了这个基本单元测试类,所有单元测试都扩展了这个类。每当我想创建一个新的 交易 createNewSessionAndTransaction() . 为了提交会话事务,我调用 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();
       }
    
    }
    
        3
  •  -1
  •   ACV    9 年前

    尝试将此添加到控制器方法:

    @Transactional(readOnly = true)