I'm building a JAR file, deploying to JBoss 4.2.3.GA (can't help it), with Hibernate 4.1.5.SP1 with validator 4.3.0.Final. The database is MySQL 5.5. I'm having problems executing basic selects using a RESOURCE_LOCAL EntityManager. I have
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;
}
Here's my META-INF/persistence.xml file …
<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>
and here's the hibernate config file …
<?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>
During the first loop, everything's fine, but the second time around, I get this exception. If I don't close the EntityManager, I get transaction timeouts after 5 minutes (the length of my JBoss transaction timeout), so I'm confused as to how I should be coding this. I want to continue to use Hibernate's 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)
Thanks, - Dave
Edit: Trying Tiago's response works until my code has run longer than the setting in the $JBOSS_HOME/server/default//conf/jboss-service.xml
400
Exactly 400 seconds after I start, I get the exception below
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)
The error you are receiving is simply because you are closing your EntityManager in finally construct inside the for loop. So the second time you try to call em.getDelegate()
, your EM is already closed. No, you do not want to close it manually. You would have something like:
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
As for the problem with the timeout, maybe you're facing a common problem between JPA and Hibernate. Take a look at this post, that might help you. Maybe the problem is the way you're getting the Hibernate Session from the EM. Also, this question is concerning the same problem.
If none of that helps, just write a comment below or edit your question specifying when it times out.