views:

673

answers:

1

I have a JPA application that has specified JTA transactions in persistence.xml. For whatever reason, I have found that when using JTA, you MUST specify a JNDI data source within persistence.xml as well. This is fine, unless you are trying to go integration testing outside a container and JNDI is not available.

My questions are:

a) is there anyway to inject a jdbc datasource into my JTA transaction manager? b) if not, how do a handle a JNDI lookup during integration testing?

Edit: The error I get when firing up the integration test is:

 Caused by: org.springframework.......DataSourceLookupFailureException:
 Failed to look up JNDI DataSource with name 'java:comp/env/jdbc/myAppDataSource';
 nested exception is javax.naming.NoInitialContextException: Need to specify
 class name in environment or system property, or as an applet parameter,
 or in an application resource file:  java.naming.factory.initial
+1  A: 

I didn't experiment this myself but it is doable with a standalone transaction manager and a XA compliant datasource. With Spring 2.5, most samples use JOTM and the JotmFactoryBean and the XAPool. But these are non longer supported in Spring 3.0 and Atomikos appears to be the "replacement" (it provides a standalone transaction manager and a XA datasource). I've added some configuration samples below.

The alternative would be to run in-container tests (using an embedded Java EE container e.g. GlassFish v3 Embedded or an API like Cargo).

Resources

Pascal Thivent
The link to JotmFactoryBean is broken. In fact, that class is missing from Spring-tx 3.0.1. I am trying to use Atomikos as the standalone transaction manager. However, Spring (or JPA/Hibernate) is continuing to try and look for the JTA data source from jndi that was specified in persistence.xml.
HDave
@HDave Indeed, I didn't noticed that but the JOTM stuff has been removed from Spring 3.x (for a good reason I guess). I've updated my answer. Regarding JPA, I think that you'll need the trick described in this [blog post](http://erich.soomsam.net/2007/04/24/spring-jpa-and-jta-with-hibernate-and-jotm/) (that I understand better now).
Pascal Thivent
@Pascal - I've read the resources extremely carefully. I see that the important thing is to "tell" Hibernate about Atomikos via hibernate.transaction.factory_class and manager_lookup_class -- GREAT!. But in all cases, I see that the Entity Manager configuration is supplying a data source. According to the Spring javadocs on dataSource "In JPA speak, a DataSource passed in here will be used as "nonJtaDataSource" on the PersistenceUnitInfo passed to the PersistenceProvider, overriding data source configuration in persistence.xml (if any)."It seems that the EM is in RESOURCE_LOCAL mode!!
HDave
@HDave I'll reread this more carefully later but I thought this was the point of using the `JtaPersistenceUnitPostProcessor` from http://erich.soomsam.net/2007/04/24/spring-jpa-and-jta-with-hibernate-and-jotm/.
Pascal Thivent
@Pascal -- I've implemented the JtaPersistenceUnitPostProcessor as outlined in that document and in combination with the hibernate.transaction.factory_class and manager_lookup_class it appears to be working. Who knew just running JPA/JTA outside a container was so hard!!!
HDave