Hibernate Session关闭了问题!

时间:2010-06-29 09:25:07

标签: hibernate session jsf hql

下面的函数是我的Web应用程序中的按钮的actionListener,我正在从数据库中的表中删除旧的选定行并将新的行插入数据库。

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

我一直有例外:会议已经结束!!有人可以解释如何在休眠中自动关闭会话(自动??)以及如何使用它们。

这是异常的详细堆栈跟踪:

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 个答案:

答案 0 :(得分:7)

如果有人在Hibernate中遇到此问题,我会在这个问题here中找到一个简明的答案。显然它很简单!

在hibernate中使用托管会话来简化单元测试06nov06

如果您曾尝试在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)
   ....

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

要解决此问题,最好的选择是使用managed个会话。使用托管会话,您可以完全控制创建,刷新,提交和关闭会话。这是怎么回事。

hibernate.cfg.xml将财产current_session_context_class更改为managed

要创建session并在transaction中开始session,请执行此操作...

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

commit transaction session ManagedSessionContext.unbind(HibernateUtil.getSessionFactory()); session.flush(); session.getTransaction().commit(); session.close(); 执行此操作...

session

要在单元测试中使用此代码,我创建了所有单元测试扩展的基本单元测试类。每当我想要创建新的transactioncreateNewSessionAndTransaction()时,我都会调用方法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(); } }

{{1}}

答案 1 :(得分:4)

您正在使用会话作用域托管bean中的延迟抓取,而Hibernate会话显然已配置为基于请求。

长话短说:Understanding Lazy Fetching in Hibernate

答案 2 :(得分:-1)

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

@Transactional(readOnly = true)