transactional data-source in web.xml doesn't close connections
henk53 Apr 15, 2012 2:00 PMUsing JBoss AS 7.1.1 I defined a data source in web.xml using the data-source element. It points to the embedded h2 database provided by JBoss AS.
When I use this data-source for a persistence unit in the same web module, JPA using an injected entity manager in an EJB seems to work, but updates are not really persisted. The h2 log file complains that connections are not being closed.
This is the definition in web.xml:
<data-source> <name>java:app/MyApp/myDS</name> <class-name>org.h2.jdbcx.JdbcDataSource</class-name> <url>jdbc:h2:~/mydb;DB_CLOSE_DELAY=-1</url> <user>sa</user> <password>sa</password> </data-source>
persistence.xml:
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="example"> <jta-data-source>java:app/MyApp/myDS</jta-data-source> </persistence-unit> </persistence>
excerpt from the exception:
org.h2.message.DbException: The connection was not closed by the application and is garbage collected [90018-161] at org.h2.message.DbException.get(DbException.java:169) at org.h2.message.DbException.get(DbException.java:146) at org.h2.message.DbException.get(DbException.java:135) at org.h2.jdbc.JdbcConnection.closeOld(JdbcConnection.java:174) at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:121) at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:94) at org.h2.Driver.connect(Driver.java:72) at org.h2.jdbcx.JdbcDataSource.getJdbcConnection(JdbcDataSource.java:181) at org.h2.jdbcx.JdbcDataSource.getXAConnection(JdbcDataSource.java:315) at org.jboss.as.ee.datasource.DataSourceTransactionProxyHandler.invoke(DataSourceTransactionProxyHandler.java:64) at org.h2.jdbcx.JdbcDataSource$$DataSourceProxy1.getConnection(Unknown Source) at org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider.getConnection(InjectedDataSourceConnectionProvider.java:67) at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:276) at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:297) at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:169) at org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler.extractPhysicalConnection(ConnectionProxyHandler.java:82) at org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler.continueInvocation(ConnectionProxyHandler.java:138) at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81) at $Proxy24.prepareStatement(Unknown Source) at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.buildBatchStatement(AbstractBatchImpl.java:144) at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.getBatchStatement(AbstractBatchImpl.java:127) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2827) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3290) at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:80) at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:272) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:264) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:186) at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1081) at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:315) at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:104) at org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:53) at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:76) at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:273) at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:93) at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:164) at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1165) at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:117) at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:75) at org.jboss.as.ejb3.tx.CMTTxInterceptor.endTransaction(CMTTxInterceptor.java:92) at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:232) at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:304) at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:190) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:59) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:32) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:165) at org.jboss.as.ee.component.ViewDescription$1.processInvocation(ViewDescription.java:173) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) at org.jboss.as.ee.component.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:72)
When I set transactional to false in the data-source definition in web.xml, the exceptions vanish and everything works:
<data-source> <name>java:app/MyApp/myDS</name> <class-name>org.h2.jdbcx.JdbcDataSource</class-name> <url>jdbc:h2:~/mydb;DB_CLOSE_DELAY=-1</url> <user>sa</user> <password>sa</password> <transactional>false</transactional> </data-source>
If I define approximately the same in standalone.xml in the JBoss specific way, then I don't need to turn off transactions (the by default available ExampleDS does exactly the same).
Did I do something wrong or is the data-source implementation faulty here?