I am tired of banging my head around this problem So if anyone could suggest me where I am wrong I'll be grateful.
The problem is I am using Spring-Batch and Hibernate Full-Text Search in my Spring MVC project.So from the batch job Tasklet I am calling following code:
A a=aDao.merge(a);
b.setA(a);
bDao.save(b);
While doing the save update on these entites I am getting an exception and the stacktrace is as follows:
org.springframework.orm.hibernate3.HibernateSystemException: Error while indexing in Hibernate Search (before transaction completion); nested exception is org.hibernate.HibernateException: Error while indexing in Hibernate Search (before transaction completion)
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:690)
at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:147)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:264)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:76)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:367)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:214)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:143)
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:250)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:135)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:61)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:144)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:124)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:281)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:120)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: org.hibernate.HibernateException: Error while indexing in Hibernate Search (before transaction completion)
at org.hibernate.search.backend.impl.EventSourceTransactionContext$DelegateToSynchronizationOnBeforeTx.doBeforeTransactionCompletion(EventSourceTransactionContext.java:175)
at org.hibernate.engine.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:543)
at org.hibernate.engine.ActionQueue.beforeTransactionCompletion(ActionQueue.java:216)
at org.hibernate.impl.SessionImpl.beforeTransactionCompletion(SessionImpl.java:571)
at org.hibernate.jdbc.JDBCContext.beforeTransactionCompletion(JDBCContext.java:250)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:138)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
... 21 more
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
at org.hibernate.search.util.HibernateHelper.unproxy(HibernateHelper.java:62)
at org.hibernate.search.engine.DocumentBuilderIndexedEntity.buildDocumentFields(DocumentBuilderIndexedEntity.java:394)
at org.hibernate.search.engine.DocumentBuilderIndexedEntity.buildDocumentFields(DocumentBuilderIndexedEntity.java:481)
at org.hibernate.search.engine.DocumentBuilderIndexedEntity.buildDocumentFields(DocumentBuilderIndexedEntity.java:481)
at org.hibernate.search.engine.DocumentBuilderIndexedEntity.getDocument(DocumentBuilderIndexedEntity.java:379)
at org.hibernate.search.engine.DocumentBuilderIndexedEntity.createAddWork(DocumentBuilderIndexedEntity.java:317)
at org.hibernate.search.engine.DocumentBuilderIndexedEntity.addWorkToQueue(DocumentBuilderIndexedEntity.java:295)
at org.hibernate.search.engine.WorkPlan$PerEntityWork.enqueueLuceneWork(WorkPlan.java:445)
at org.hibernate.search.engine.WorkPlan$PerClassWork.enqueueLuceneWork(WorkPlan.java:246)
at org.hibernate.search.engine.WorkPlan.getPlannedLuceneWork(WorkPlan.java:150)
at org.hibernate.search.backend.WorkQueue.prepareWorkPlan(WorkQueue.java:134)
at org.hibernate.search.backend.impl.BatchedQueueingProcessor.prepareWorks(BatchedQueueingProcessor.java:124)
at org.hibernate.search.backend.impl.PostTransactionWorkQueueSynchronization.beforeCompletion(PostTransactionWorkQueueSynchronization.java:89)
at org.hibernate.search.backend.impl.EventSourceTransactionContext$DelegateToSynchronizationOnBeforeTx.doBeforeTransactionCompletion(EventSourceTransactionContext.java:172)
... 27 more
I am not getting whats gone wrong.I am using org.springframework.orm.hibernate3.HibernateTransactionManager and my Spring version is 3.2 Hibernate core version is 3.6 final.
Note :This exception occurs often but When I create a new tables or use fresh db it works like charm and all modification/insertion are getting reflected properly in database.Can somebody explain me this behavior or Have i done something fishy.
Tell me if you need more details.
Thank you.
Code Update:
<batch:job-repository id="jobRepository"
data-source="myJNDI"
transaction-manager="transactionManager"
isolation-level-for-create="READ_COMMITTED"
max-varchar-length="2500"
lob-handler="defaultLobHandler"
/>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="safeSessionFactory" />
</bean>
Like this I am configuring transaction manager in applicationContext.xml for Spring-Batch.And I have tried doing this with manually opening and closing session with manual commit of transaction but the exception remains same.And yes I have annotated my method as #Transactional.
I found the root cause of problem is Spring's Declarative Transaction Management.
Spring Batch in Action Reference:
Disable Spring’s declarative transactions for your batch application—Don’t use the tx:annotation-driven element or any XML
configuration related to declara- tive transaction management.
Be careful using propagation levels if declarative transactions are on—If you call trans- actional classes from a Spring Batch job,
Spring’s transaction propagation can interfere with the Spring Batch
transaction because of the propagation level. The REQUIRES_NEW
propagation level could typically cause problems because the
application code runs in its own transaction, independent of the
Spring Batch transaction.
The following are guidelines to avoid conflict between Spring Batch–managed and
Spring-managed transactions:
Related
I am seeing the following error upon upgrading my application from hibernate 5.1 to 5.2.6. Specifically, this is spring 4.3.5.
javax.persistence.TransactionRequiredException: no transaction is in progress
org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3450)
org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1418)
org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1414)
org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:144)
org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95)
org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95)
org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:932)
org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:744)
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:504)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
com.sun.proxy.$Proxy140.mapUserFromContext(Unknown Source)
org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider.authenticate(AbstractLdapAuthenticationProvider.java:87)
As you can see in the stack trace below, spring clearly has started a transaction , and is actually trying to trigger a flush before committing it's transaction. It appears that the code that syncronizes hibernate and spring transactions is not working with hibernate 5.2 (looks to be located at the end of org.springframework.orm.hibernate5.SpringSessionContext.currentSession()). Is this an open bug, or am I missng a config somewhere?
In my case, the issue was caused by an old configuration setting using Spring's JDBC TransactionManager implementation, rather than the appropriate Hibernate-integrated one. This was apparently acceptable for Hibernate 4.1, but not for 5.2. The fix was to change my transaction manager bean declaration to:
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="dataSource" ref="dataSource"/>
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
I encountered the same problem when upgrading a legacy application that is backed by Spring XML configuration.
The following hibernate properties had to be added to the Spring LocalSessionFactory configuration:
<prop key="hibernate.transaction.coordinator_class">jta</prop>
<prop key="hibernate.transaction.jta.platform">JBossAS</prop>
The reason seems to be that with Hibernate 5.2 the default value for hibernate.transaction.coordinator_class is jdbc for non-JPA applications. And that doesn't play well with Spring transactions.
We are facing the same problem, I found the different reason for it.
Spring 4.3.9 , Hibernate 5.2.10 with XML Configuration & Declarative transaction.
Problem was setReadOnly() placed at wrong place in transaction, it sets after the getTransaction()
Code With error:
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
transactionStatus = transactionManager.getTransaction(transactionDefinition);
transactionDefinition.setReadOnly(true); //wrongly set it will not set in transactionstatus
//DAO Call
transactionManager.commit(transactionStatus);
Changes in above code for fixing the issue:
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
transactionDefinition.setReadOnly(true);
transactionStatus = transactionManager.getTransaction(transactionDefinition);
//DAO Call
transactionManager.commit(transactionStatus);
I was facing the same exception when we upgraded our spring-boot-dependencies bundle from 1.5 to 2.0.2 (which effectively upgrades spring 4 to 5, and hibernate 5.0 to 5.2).
I had a test case that was marked #Transactional which internally invokes an internal method that was marked #Transactional(propagation=Propagation.NOT_SUPPORTED) as it had some stuff that shouldn't be a part of the upstream transaction. Started getting the below error after the upgrade which was working fine with Spring 4 and Hibernate 5.0 combination.
javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3505)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1427)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1423)
at org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:147)
at org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95)
at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:96)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:922)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:730)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:532)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:304)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
It was resolved by adding 'readOnly = true' attribute to the method where a transaction wasn't needed - #Transactional(readOnly = true, propagation=Propagation.NOT_SUPPORTED). It appears that newer versions will need this to indicate or serve as a hint to the calling transaction subsystem. Check readOnly attribute docs.
Also, do check the accepted answer here for a similar explanation.
Facing issue in session with the upgrade of my application to Spring 4.1.9 and Hibernate 4.3.11..Logs are below:
[org.springframework.orm.hibernate4.HibernateTemplate] - <Could not retrieve pre-bound Hibernate session>
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
at org.springframework.orm.hibernate4.HibernateTemplate.doExecute(HibernateTemplate.java:325)
at org.springframework.orm.hibernate4.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:308)
at org.springframework.orm.hibernate4.HibernateTemplate.findByCriteria(HibernateTemplate.java:1011)
at org.springframework.orm.hibernate4.HibernateTemplate.findByCriteria(HibernateTemplate.java:1003)
There may be below possible reason:
1) You need to put #Repository on class of DAO layer where you are trying to access session.
1) You need to put #Transactional below #Repository on class of DAO layer where you are trying to access session.
3) Your container is not able to find bean definition file where you have declared session factory and Transaction.
I have a situation where I have to handle multiple clients in one app and each client has separate database. To support that I'm using Spring custom scope, quite similar to the built in request scope. A user authenticates in each request and can set context client ID based passed credentials. The scoping itself seems to be working properly.
So I used my custom scope to create a scoped-proxy for my DataSource to support a diffrent database per client. And I get connections to proper databases.
Than I created a scoped-proxy for EntityManagerFactory to use JPA. And this part also looks OK.
Than I added a scoped-proxy for PlatformTransactionManager for declarative transaction management. I use #Transactional on my service layer and it gets propagated nicely to my SpringData powered repository layer.
All is fine and works correctly as long a s I use only JPA. I can even switch context to a diffrent client within the request (I use ThreadLocals under the hood) and transactions to both databases are handled correctly.
The problems start when I try to use JDBCTempate in one of my custom repositiries. Than at first glance all looks OK too, as no exceptions are thrown. But when I check the database for the objects I thought I inserted with my custom JDBC-based repository the're not there!
I know for sure I can use JPA and JDBC together by declaring only JpaTransactionManager and passing both the DataSource and EntityManagerFactory to it - I checked it and without the scoped-proxies and it works.
So the question is how to make JDBC work together with JPA using the JpaTransactionManager when I have scoped-proxied the DataSource, EntityManagerFactory and PlatformTransactionManager beans? I remind that using only JPA works perfectly, but adding plain JDBC into the mix is not working.
UPDATE1: And one more thing: all readonly (SELECT) operations work fine with JDBC too - only writes (INSERT, UPDATE, DELETE) end up not commited or rolledback.
UPDATE2: As #Tomasz suggested I've removed scoped proxy from EntityManagerFactory and PlatformTransactionManager as those are indeed not needed and provide more confusion than anything else.
The real problem seems to be switching the scope context within a transaction. The TransactionSynchronizationManager bounds transactional resources (i.e. EMF or DS) to thread at transaction start. It has the ability to unwrap the scoped proxy, so it binds the actual instance of the resource from the scope active at the time of starting a transaction. Then when I change the context within a transaction it all gets messed up.
It seems like I need to suspend the active transaction and store aside the current transaction context to be able to clear it upon entering another scope to make Spring think it's not inside a transaction any more and to force it create one for the new scope when needed. And then when leaving the scope I'd have to restore the previously suspended transaction. Unfortunatelly I was unable to come up with a working implementation yet. Any hints appreciated.
And below is some code of mine, but it's pretty standard, except for the scoped-proxies.
The DataSource:
<!-- provides database name based on client context -->
<bean id="clientDatabaseNameProvider"
class="com.example.common.spring.scope.ClientScopedNameProviderImpl"
c:clientScopeHolder-ref="clientScopeHolder"
p:databaseName="${base.db.name}" />
<!-- an extension of org.apache.commons.dbcp.BasicDataSource that
uses proper database URL based on database name given by above provider -->
<bean id="jpaDataSource" scope="client"
class="com.example.common.spring.datasource.MysqlDbInitializingDataSource"
destroy-method="close"
p:driverClassName="${mysql.driver}"
p:url="${mysql.url}"
p:databaseNameProvider-ref="clientDatabaseNameProvider"
p:username="${mysql.username}"
p:password="${mysql.password}"
p:defaultAutoCommit="false"
p:connectionProperties="sessionVariables=storage_engine=InnoDB">
<aop:scoped-proxy proxy-target-class="false" />
</bean>
The EntityManagerFactory:
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:database="MYSQL"
p:generateDdl="true"
p:showSql="true" />
<util:properties id="jpaProperties">
<!-- omitted for readability -->
</util:properties>
<bean id="jpaDialect"
class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:packagesToScan="com.example.model.core"
p:jpaVendorAdapter-ref="jpaVendorAdapter"
p:dataSource-ref="jpaDataSource"
p:jpaDialect-ref="jpaDialect"
p:jpaProperties-ref="jpaProperties" />
The PlatformTracsactionManager:
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager"
p:dataSource-ref="jpaDataSource"
p:entityManagerFactory-ref="entityManagerFactory" />
<tx:annotation-driven proxy-target-class="false" mode="proxy"
transaction-manager="transactionManager" />
I have 2 tables, say Item and Property and a hibernate object mapped to both. The mapping for table Item to Property looks like
<set name="propertySet" cascade="all-delete-orphan">
<key column="item_id" not-null="true"/>
<one-to-many class="Property"/>
</set>
An item can have multiple properties. Everything like select, insert works properly. but when there is an error, the inserts to the property table do not rollback.
What happens is that if i am editing an item with N properties and enter an invalid value in a field, the next time I retrieve the item, it has 2*N properties.
Edit ---
What my class looks like is
#Autowired
SessionFactory sessionFactory
#Transactional
public void updateItem(Item i){
...
// The only 2 statements dealing with hibernate or session in this function
ItemModel im = sessionFactory.getCurrentSession().get(...);
sessionFactory.getCurrentSession().update(updatedItem);
...
}
I am using annotated transactions (#Transactional) with the spring framework and the lowest exception getting thrown is
Caused by: org.springframework.transaction.TransactionSystemException: Could not roll back Hibernate transaction; nested exception is org.hibernate.Tra
nsactionException: Transaction not successfully started
at org.springframework.orm.hibernate3.HibernateTransactionManager.doRollback(HibernateTransactionManager.java:679)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:845)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:822)
at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:412)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:111)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
Caused by: org.hibernate.TransactionException: Transaction not successfully started
at org.hibernate.transaction.JDBCTransaction.rollback(JDBCTransaction.java:183)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doRollback(HibernateTransactionManager.java:676)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:845)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:822)
at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:412)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:111)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
...
...
at org.apache.catalina.valves.SSLValve.invoke(SSLValve.java:113)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11NioProcessor.process(Http11NioProcessor.java:894)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:719)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:2101)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Transactions don't "cascade". At the JDBC level, a transaction consists of:
Turning off autocommit
Executing some statements
Calling java.sql.Connection.commit() or java.sql.Connection.rollback().
If you're saying that some things are being committed and some are rolled back, then there's something wrong in your transaction management. Either autocommit is on or you actually have multiple calls to commit() happening.
Transactions are managed under the hood by Spring if you do the following: in your XML config, you need to 1) enable transactions, and 2) configure a transaction manager, as follows:
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="mainSessionFactory" />
</bean>
Tx schemaLocation is http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
I am having a problem getting a JDBC connection in an EJB SessionBean. The error is:
org.jboss.util.NestedSQLException: Could not enlist in transaction on entering meta-aware object!; - nested throwable: (javax.transaction.SystemException: java.lang.Throwable: Unabled to enlist resource, see the previous warnings.
I thought this happens, because I already have an open connection from a different datasource, so I configured an XA datasource to avoid transaction problems, but it doesn't work at all, so I don't know if I am doing something wrong in my code. Here it is:
try
{
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
p.put(Context.PROVIDER_URL,"jnp://localhost:11099");
p.put("java.naming.factory.url.pkgs", "org.jboss.naming");
InitialContext ic = new InitialContext(p);
DataSource dataSource = (DataSource)ic.lookup("java:/jdbc/etlreportservices");
return dataSource.getConnection();
}
catch(Exception e)
{
e.printStackTrace();
}
The exception is thrown while calling dataSource.getConnection().
Can try,
for old Jboss-es:
/server/all/conf/jbossjta-properties.xml
<properties depends="arjuna" name="jta">
<property name="com.arjuna.ats.jta.allowMultipleLastResources" value="true"/>
</properties>
for new:
standalone\configuration\standalone.xml (or other what you use)
<system-properties>
<property name="com.arjuna.ats.arjuna.allowMultipleLastResources" value="true"/>
</system-properties>
I have noticed this in cases where the tx times out. FWIW.
Using JBoss 6.0.0, the error message is slightly different:
Caused by: org.jboss.resource.JBossResourceException: Could not enlist in transaction on entering meta-aware object!
As for the reason: A quote from here
Within the same process, two calls were being made to different non-XA data sources. This is not supported by default on JBoss.
The same site shows a solution which was not applicable for JBoss 6.0.0.
The general solution is to change all data sources involved in the same transaction into XA data sources. Then it works both with bean managed and container managed transactions. For example, this solution is proposed in a CodeRanch and in a JBoss forum as well.
I changed my transaction manager to be bean-managed and it works perfectly.