【问题标题】:java.lang.IllegalStateException: EntityManager is closedjava.lang.IllegalStateException:EntityManager 已关闭
【发布时间】:2012-08-13 05:35:18
【问题描述】:

我正在构建一个 JAR 文件,部署到 JBoss 4.2.3.GA(忍不住),使用 Hibernate 4.1.5.SP1 和验证器 4.3.0.Final。数据库是 MySQL 5.5。我在使用 RESOURCE_LOCAL EntityManager 执行基本选择时遇到问题。我有

        for (final Order order : results) { 
        ...                 
                    try { 
                        session = (Session)em.getDelegate();
                        state = findStateByAbbrev(stateAbbrev, session);
                    } catch (HibernateException e) {
                        e.printStackTrace(System.err);
                        LOG.error(e.getMessage(), e);
                    } finally {
                        em.close();
                    }   // try 

        }   // for

private State findStateByAbbrev(final String abbrev, final Session session) {
    State ret = null;
    final Criteria crit = session.createCriteria(State.class).add(Restrictions.eq("abbrev", abbrev));
    final List<State> results = crit.list();
    if (results != null && results.size() > 0) {
        ret = results.get(0);
    }   // if
    return ret;
}

这是我的 META-INF/persistence.xml 文件……

<persistence>
    <persistence-unit name="didoclientunit" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <non-jta-data-source>java:/MySqlDS</non-jta-data-source>
        <properties>
            <property name="hibernate.ejb.cfgfile" value="hibernate.cfg.xml" />
            <property name="hibernate.validator.apply_to_ddl">false</property>
            <property name="hibernate.validator.autoregister_listeners">false</property>
            <property name="hibernate.transaction.manager_lookup_class" value=" org/hibernate/transaction/TransactionManagerLookup"/> -->
        </properties>
    </persistence-unit>
</persistence>

这是休眠配置文件……

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="show_sql">true</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <mapping class="com.parentco.fdr.myproject.model.UserRole" />
        <mapping class="com.parentco.fdr.myproject.model.Organization" />
        <mapping class="com.parentco.fdr.myproject.model.Product" />
        <mapping class="com.parentco.fdr.myproject.model.State" />
        <mapping class="com.parentco.fdr.myproject.model.Country" />
        <mapping class="com.parentco.fdr.myproject.model.AccessCode" />
        <mapping class="com.parentco.fdr.myproject.model.Contract" />
        <mapping class="com.parentco.fdr.myproject.model.TrainingLink" />

    </session-factory>
</hibernate-configuration>

在第一个循环中,一切都很好,但是第二次,我得到了这个异常。如果我不关闭 EntityManager,我会在 5 分钟后得到事务超时(我的 JBoss 事务超时的长度),所以我对应该如何编码感到困惑。我想继续使用 Hibernate 的 Criteria API。

java.lang.IllegalStateException: EntityManager is closed
    at org.hibernate.ejb.EntityManagerImpl.close(EntityManagerImpl.java:58)
    at org.mainco.subco.dido.service.OrderServiceImpl.getPDOrders(OrderServiceImpl.java:153)
    at org.mainco.subco.dido.quartz.ProcessPDWorker.work(ProcessPDWorker.java:24)
    at org.mainco.subco.dido.quartz.ProcessPDJob.execute(ProcessPDJob.java:42)
    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.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
    at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
    at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
    at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:195)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.mdb.MessagingContainer.localInvoke(MessagingContainer.java:249)
    at org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.delivery(MessageInflowLocalProxy.java:268)
    at org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.invoke(MessageInflowLocalProxy.java:138)
    at $Proxy83.execute(Unknown Source)
    at org.jboss.resource.adapter.quartz.inflow.QuartzJob.execute(QuartzJob.java:57)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:203)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520)

谢谢,- 戴夫

编辑:尝试 Tiago 的响应直到我的代码运行时间超过 $JBOSS_HOME/server/default//conf/jboss-service.xml 中的设置为止

400

刚开始 400 秒后,我得到以下异常

21:41:40,025 WARN  [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.BasicAction_58] - Abort of action id -3f57ff9c:ca5e:502dadac:34 invoked while multiple threads active within it.
21:41:40,026 WARN  [arjLoggerI18N] [com.arjuna.ats.arjuna.coordinator.CheckedAction_2] - CheckedAction::check - atomic action -3f57ff9c:ca5e:502dadac:34 aborting with 1 threads active!
21:41:40,410 WARN  [JDBCExceptionReporter] SQL Error: 0, SQLState: null
21:41:40,410 ERROR [JDBCExceptionReporter] Transaction is not active: tx=TransactionImple < ac, BasicAction: -3f57ff9c:ca5e:502dadac:34 status: ActionStatus.ABORTED >; - nested throwable: (javax.resource.ResourceException: Transaction is not active: tx=TransactionImple < ac, BasicAction: -3f57ff9c:ca5e:502dadac:34 status: ActionStatus.ABORTED >)
21:41:40,412 ERROR [STDERR] org.hibernate.exception.GenericJDBCException: Cannot open connection
    at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:29)
    at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:426)
    at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:144)
    at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:139)
    at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1547)
    at org.hibernate.loader.Loader.doQuery(Loader.java:673)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
    at org.hibernate.loader.Loader.doList(Loader.java:2220)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
    at org.hibernate.loader.Loader.list(Loader.java:2099)
    at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:94)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1569)
    at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
    at org.mainco.subco.dido.service.OrderServiceImpl.findStateByAbbrev(OrderServiceImpl.java:450)
    at org.mainco.subco.dido.service.OrderServiceImpl.getPDOrders(OrderServiceImpl.java:144)
    at org.mainco.subco.dido.quartz.ProcessPDWorker.work(ProcessPDWorker.java:24)
    at org.mainco.subco.dido.quartz.ProcessPDJob.execute(ProcessPDJob.java:42)
    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.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
    at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
    at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
    at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:195)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.mdb.MessagingContainer.localInvoke(MessagingContainer.java:249)
    at org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.delivery(MessageInflowLocalProxy.java:268)
    at org.jboss.ejb3.mdb.inflow.MessageInflowLocalProxy.invoke(MessageInflowLocalProxy.java:138)
    at $Proxy83.execute(Unknown Source)
    at org.jboss.resource.adapter.quartz.inflow.QuartzJob.execute(QuartzJob.java:57)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:203)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520)

【问题讨论】:

    标签: hibernate jboss entitymanager hibernate-entitymanager


    【解决方案1】:

    您收到的错误仅仅是因为您在 for 循环内的 finally 构造中关闭了 EntityManager。因此,当您第二次尝试拨打 em.getDelegate() 时,您的 EM 已经关闭。不,您不想手动关闭它。你会有类似的东西:

    session = (Session)em.getDelegate();
    for (final Order order : results) { 
            ...                 
                        try { 
    
                            state = findStateByAbbrev(stateAbbrev, session);
                        } catch (HibernateException e) {
                            e.printStackTrace(System.err);
                            LOG.error(e.getMessage(), e);
                        } 
    
            }   // for
    

    关于超时的问题,也许你正面临着 JPA 和 Hibernate 之间的共同问题。看看this post,这可能会对你有所帮助。也许问题在于您从 EM 获取休眠会话的方式。此外,this question 也涉及同样的问题。

    如果这些都没有帮助,只需在下面写评论或编辑您的问题,指定超时时间。

    【讨论】:

    • 您的建议有效,直到我达到 JBoss 中的超时限制,此时我得到一个“事务未激活:”异常(包括在上面)。我怎样才能让每个调用都有自己的工作单元?
    • 您能否调试您的代码以准确查看它在哪一行停止?
    • 另一件事:您使用的是 JPA2 吗?如果是这样,请尝试使用:Session session = entityManager.unwrap(Session.class);而不是 getDelegate。
    • 我包含了完整的堆栈跟踪,但我无法确定所有中断的确切行。正如我所说,在事务超时设置后,错误始终出现在日志中。根据您的其他建议,我得到了 NoSuchMethodError。在这一点上,我不介意使用 JPA 1 或 2。谢谢,
    • 好的。看起来你正在使用 JPA 1。我问这个是因为我指出的链接中提到的兼容性问题。但我希望你实际调试代码,这样你就可以找出执行需要这么长时间的地方。这样您就可以一步一步地查看执行并找出它在哪里被“阻止”了你知道吗?
    猜你喜欢
    • 1970-01-01
    • 2013-02-26
    • 2019-02-22
    • 2012-12-24
    • 2016-07-26
    • 2017-10-15
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    相关资源
    最近更新 更多