Session replication with Spring cause NotSerializableException - java

I'm trying to configure tomcat 7 clustering with session replication.
I used this tutorial and everything works fine on test servlets, which are located in tomcat examples.
http://localhost/examples/servlets/servlet/SessionExample.
So I added some attributes and then stopped one of the nodes, and session was replicated successfully.
But when I move this configuration to my application with hibernate + spring mvc + spring security, And when I've tried to login I always get exception
SEVERE: Unable to serialize delta request for sessionid [69845CF0E87B3F0F64FB605FAC1D4987.node1]
java.io.NotSerializableException: org.apache.commons.dbcp.BasicDataSource
All my session objects implement Serializable interface, in web.xml I've added
I've tried make EntityManager field transient, but it doesn't help. I think that it can be that spring tries to save some bean to session, but I've searched through project and didn't find any session scoped beans.
Does anybody have ideas how to deal with this issue?
UPD:
public abstract class AbstractDAOImpl<E, I> implements AbstractDAO<E, I> {
private static final long serialVersionUID = 7372882616977337461L;
#PersistenceContext
protected transient EntityManager entityManager;
applicationContext.xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
p:driverClassName="${jdbc-driver}" p:url="${jdbc-db-url}" p:username="${jdbc-db-username}"
p:password="${jdbc-db-passwd}" p:testWhileIdle="true"
p:timeBetweenEvictionRunsMillis="7200000" p:validationQuery="select 1;"
destroy-method="close" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="MIQlocal" />
<property name="dataSource" ref="dataSource" />
<property name="jpaDialect" ref="jpaDialect" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
</bean>
<bean id="transactionManager" name="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource" />
</bean>

Your datasource is not Serializable.
Make your class field that is an instance of org.apache.commons.dbcp.BasicDataSource transient and make sure it is injected by Spring and you're done.
edit: just now I see that you have made the EntityManager transient, so I must ask that you provide the relevant code if possible.

Related

EclipseLink JPA in WAS Liberty Profile

Has anyone been able to get the EclipseLink JPA povider working in WAS Liberty Profile with Container Managed Transactions? I have configured my server.xml file with the JPA Container setting to override the default OpenJPA implementations however this causes a side effect where by the EntityManager no longer participates in a Container transaction when accessed through an EJB that has a transaction propagation annotation.
I also tried setting the "eclipselink.target-server" property to "WebSpeher_7" however when I do this I get a ClassNotFoundException on the com.ibm.ws.Transaction.TransactionManagerFactory class.
Good afternoon. This looks like you're hitting Bug 407279 (https://bugs.eclipse.org/bugs/show_bug.cgi?id=407279).
You can work around this issue by modifying org.eclipse.persistence.transaction.was.WebSphereTransactionController with the following change:
public class WebSphereTransactionController extends JTATransactionController {
// Class and method to execute to obtain the TransactionManager
protected final static String TX_MANAGER_FACTORY_CLASS = "com.ibm.tx.jta.TransactionManagerFactory";
// OLD VALUE --> "com.ibm.ws.Transaction.TransactionManagerFactory";
Hope this helps! Be sure to grab EclipseLink 2.5.2 as that has another important change (Bug 412627) in order to work with Liberty!
I had to change many things with liberty 16.0.0.2, Spring 4.X and EclipseLink 5.2.X
I removed the persistence.xml file
and changed the spring xml configuration to:
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="datasource" />
<property name="persistenceUnitName" value="PERSISTENCE_UNIT"></property>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
<property name="packagesToScan">
<list>
<value>ENTITIES_PACKAGE</value>
</list>
</property>
<property name="jpaPropertyMap">
<map>
<entry key="eclipselink.weaving" value="false"/>
</map>
</property>
</bean>
And for server.xml
<jpa defaultPersistenceProvider="org.eclipse.persistence.jpa.PersistenceProvider"/>
<featureManager>
<feature>servlet-3.0</feature>
<feature>jdbc-4.0</feature>
<feature>jpa-2.0</feature>
<feature>localConnector-1.0</feature>
<feature>jsp-2.2</feature>
</featureManager>

SqlSessionFactory must be using a SpringManagedTransactionFactory in order to use Spring transaction synchronization

I've got an app running on Tomcat 7, using Spring, Mybatis, and .. Mybatis-spring.
Here's the setup for the DB and transactions in servlet-context.xml:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDS" />
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:maps/*.xml" />
<property name="transactionFactory">
<bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />
</property>
</bean>
<mybatis:scan base-package="com.domain.dao.mappers" />
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
The error I'm getting when I run a method that uses the SqlSession is the following:
org.springframework.dao.TransientDataAccessResourceException: SqlSessionFactory must be using a SpringManagedTransactionFactory in order to use Spring transaction synchronization
at org.mybatis.spring.SqlSessionUtils.getSqlSession(SqlSessionUtils.java:136)
What am I doing wrong?
My goal, really, is just to use transactions with this setup. I don't think I necessarilly need JTA. But if that's easy enough to setup on Tomcat, I'm willing to take a swing at it.
And I solved the problem myself. Really simple solution. In case anyone runs into the same issue, all I needed to do is remove the following from the sqlSessionFactory bean:
<property name="transactionFactory">
<bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />
</property>
I must have somehow entered it thinking I needed it, but apparently it's only needed if you're not using CMT (Container Managed Transactions).
You can solve this by changing the transaction factory to
<property name="transactionFactory">
<bean class="org.mybatis.spring.transaction.SpringManagedTransactionFactory" />
</property>

EntityManager from LocalContainerEntityManagerFactoryBean does not persist entities into the database

The problem is that the EntityManager injected with #PersistenceContext in a Spring managed bean does not persist the entities to the database. I have tried using #Transactional on the AddDao bean, where entityManager.persist() is called (I have enabled annotation-driven transactions).
The transaction begins in another bean which is instantiated by Camel with .transacted() in the Camel Java DSL. That bean has an #Autowired property which is the DAO and has the EntityManager injected with #PersistenceContext.
As transaction manager Bitronix is used.
A portion of the Spring xml configuration file looks like this:
<bean id="localContainerEntityManagerFactoryBean" depends-on="btmConfig" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jtaDataSource" ref="dataSource"/>
<property name="persistenceUnitName" value="nameFromPersistenceXml"/>
<property name="persistenceProvider">
<bean class="org.hibernate.ejb.HibernatePersistence"/>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
<property name="packagesToScan" value="package with #Entity POJOs"/>
</bean>
<bean id="btmConfig" factory-method="getConfiguration"
class="bitronix.tm.TransactionManagerServices">
<property name="serverId" value="spring-btm" />
</bean>
<!-- create BTM transaction manager -->
<bean id="BitronixTransactionManager" factory-method="getTransactionManager"
class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig"
destroy-method="shutdown" />
<!-- Spring JtaTransactionManager -->
<bean id="springTransactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="BitronixTransactionManager" />
<property name="userTransaction" ref="BitronixTransactionManager" />
</bean>
<tx:annotation-driven transaction-manager="springTransactionManager" />
Edit: In a overly simplified version it looks like this:
In Camel Java DSL there is
from("wsLayer")
.transacted()
.otherProcessing()
.to("bean:addBean?method=addMyEntity")
And add beans look something like this:
#Component
public class AddBean {
#Autowired
private AddDao addDao;
public void addMyEntity(MyEntity myEntity) {
//other business logic
addDao.persistMyEntity(myEntity);
}
}
#Component
public class AddDao {
#PersistenceContext
private EntityManager entityManager;
//I have tried here
//#Transactional and
//#Transactional(propagation = PropagationType.REQUIRES_NEW)
public void persistMyEntity(MyEntity myEntity) {
entityManager.persist(myEntity);
}
}
The reading from the database works well.
See the data source:
<bean id="dataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource"
init-method="init" destroy-method="close">
<property name="uniqueName" value="theName" />
<property name="maxPoolSize" ><value>${db.pool.maxSize}</value></property>
<property name="minPoolSize" ><value>${db.pool.minSize}</value></property>
<property name="allowLocalTransactions" ><value>true</value></property>
<property name="automaticEnlistingEnabled" ><value>true</value></property>
<property name="className" ><value>${db.pool.datasource}</value></property>
<property name="driverProperties" ref="databaseProperties" />
</bean>
where the properties are set in Maven's pom.xml like this:
db.pool.maxSize=15
db.pool.maxSize=5
db.pool.datasource=org.postgresql.xa.PGXADataSource
Did you tried to execute em.flush() after em.persist(entity)?
According with the docs of Java EE:
em.persist(entity): Make an instance managed and persistent.
BUT
em.flush(entity): Synchronize the persistence context to the underlying database.
So, you can do something like:
em.persist(myEntity);
em.flush();
And check if this change make a difference.
From the limited symptoms given, seems like the JTA transaction is not being started and propagated. Your EM would work fine up to a point - reading from DB, allowing data changes against it's Persistent Context cache, but never writing to the DB.
Think it's a config problem and your #Transaction annotations are being ignored.
I have enabled annotation-driven transactions.
Make sure it's configured as follows in your Spring configuration:
<tx:annotation-driven transaction-manager="springTransactionManager"/>
where:
xmlns:tx="http://www.springframework.org/schema/tx"
Try the #Transactional in this way
#Component
public class AddDao {
#PersistenceContext
private EntityManager entityManager;
#Transactional("BitronixTransactionManager")
public void persistMyEntity(MyEntity myEntity) {
entityManager.persist(myEntity);
}
}

With spring and hibernate, need clarification on how the datasource and session are wired

My DAO's are going to extend the HibernateDaoSupport class that spring provides.
Now I need to:
setup my database connection in web.xml
Tell spring I am using annotations for hibernate mapping?
wire the session to the HibernateDaoSupport object.
The doc's show a sample xml:
<beans>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="mappingResources">
<list>
<value>product.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
</value>
</property>
</bean>
</beans>
So the 'mydatasource' configures the connection to the database, and the mySessionFactory sets up the session.
What I am confused with is, where in the code are these beans being used?
I want to create a GenericDaoImpl that extendsHibernateDaoSupport. I will then create EntityDaoImpl that extend GenericDaoImpl.
Just confused as to where 'mydatasource' and 'mysessionFactory' are used internally. Shouldn't they both be properties to HibernateDaoSupport?
Shouldn't they both be properties to
HibernateDaoSupport?
Well, SessionFactory should. The DAO won't need the DataSource, since that's used internally by the SessionFactory. Your own code should have no need for the raw DataSource, and so should not have to be injected with it.
Your DAOs (which extend HibernateDaoSupport) need to injected with the SessionFactory bean, e.g.
public class DaoA extends HibernateDaoSupport {
// business methods here, that use getHibernateTemplate()
}
public class DaoB extends HibernateDaoSupport {
// business methods here, that use getHibernateTemplate()
}
<bean id="daoA" class="DaoA">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
<bean id="daoB" class="DaoB">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>

What transaction manager should I use for JBDC template When using JPA ?

I am using standard JPA transaction manager for my JPA transactions. However, now I want to add some JDBC entities which will share the same 'datasource'. How can I make the JDBC operations transactional with spring transaction? Do I need to switch to JTA transaction managers? Is it possible to use both JPA & JDBC transactional service with same datasource? Even better, is it possible to mix these two transactions?
UPDATE:
#Espen :
I have a dao extended from SimpleJdbcDaoSupport which uses getSimpleJDBCTemplate.update to insert a database row. When a RuntimeException is thrown from the service code, the transaction never rolls back when using JPATransactionManager. It does rollback when using DatasourceTransactionManager. I tried to debug the JPATransactionManager and seems that it never performs rollback on underlying JDBCConnection(I guess due to the fact that the datasource is not necessarily has to be JDBC for JPA). My configuration setup are exactly like you explained here.
Here are my test codes:
<context:property-placeholder location="classpath:*.properties"/>
<!-- JPA EntityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceXmlLocation"
value="classpath:/persistence-test.xml" />
<property name="persistenceProvider">
<bean class="org.hibernate.ejb.HibernatePersistence" />
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!--
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
-->
<!-- Database connection pool -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${database.driverClassName}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.username}" />
<property name="password" value="${database.password}" />
<property name="testOnBorrow" value="${database.testOnBorrow}" />
<property name="validationQuery" value="${database.validationQuery}" />
<property name="minIdle" value="${database.minIdle}" />
<property name="maxIdle" value="${database.maxIdle}" />
<property name="maxActive" value="${database.maxActive}" />
</bean>
<!-- Initialize the database -->
<!--<bean id="databaseInitializer" class="com.vantage.userGroupManagement.logic.StoreDatabaseLoader">
<property name="dataSource" ref="storeDataSource"/>
</bean>-->
<!-- ANNOTATION SUPPORT -->
<!-- Enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- JPA annotations bean post processor -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<!-- Exception translation bean post processor (based on Repository annotation) -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<!-- throws exception if a required property has not been set -->
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
<bean id="userService" class="com.rfc.example.service.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
<property name="contactDao" ref="contactDao"></property>
<property name="callRecordingScheduledProgramTriggerDAO" ref="com.rfc.example.dao.CallRecordingScheduledProgramTriggerDAO"></property>
</bean>
<bean id="userDao" class="com.rfc.example.dao.UserDaoJPAImpl" />
<bean id="contactDao" class="com.rfc.example.dao.ContactDaoJPAImpl"></bean>
<bean id="com.rfc.example.dao.CallRecordingScheduledProgramTriggerDAO" class="com.rfc.example.dao.CallRecordingScheduledProgramTriggerDAOJDBCImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
AND HERE IS THE DAO:
#Transactional
public class CallRecordingScheduledProgramTriggerDAOJDBCImpl extends SimpleJdbcDaoSupport implements CallRecordingScheduledProgramTriggerDAO{
private static final Log log = LogFactory.getLog(CallRecordingScheduledProgramTriggerDAOJDBCImpl.class);
#SuppressWarnings("unchecked")
public CallRecordingScheduledProgramTrigger save(
CallRecordingScheduledProgramTrigger entity) {
log.debug("save -> entity: " + entity);
String sql = null;
Map args = new HashMap();
String agentIdsString = getAgentIdsString(entity.getAgentIds());
String insertSQL = "insert into call_recording_scheduled_program_trigger" +
" ( queue_id, queue_id_string, agent_ids_string, caller_names, caller_numbers, trigger_id, note, callcenter_id, creator_id_string, creator_id) " +
" values(:queueId, :queueIdString, :agentIdsString, :callerNames, :callerNumbers, :triggerId, :note, :callcenterId , :creatorIdString, :creatorId )";
args.put("queueId", entity.getQueueId());
args.put("agentIdsString",agentIdsString);
args.put("callerNames", entity.getCallerNames());
args.put("queueIdString", entity.getQueueIdString());
args.put("callerNumbers", entity.getCallerNumbers());
args.put("triggerId", entity.getTriggerId());
args.put("note", entity.getNote());
args.put("callcenterId", entity.getCallcenterId());
args.put("creatorId", entity.getCreatorId());
args.put("creatorIdString", entity.getCreatorIdString());
sql = insertSQL;
getSimpleJdbcTemplate().update(sql, args);
System.out.println("saved: ----------" + entity);
return entity;
}
}
Here is the client code that calls the dao and throws exception (spring service)
#Transactional(propagation=Propagation.REQUIRED)
public void jdbcTransactionTest() {
System.out.println("entity: " );
CallRecordingScheduledProgramTrigger entity = new CallRecordingScheduledProgramTrigger();
entity.setCallcenterId(10L);
entity.setCreatorId(22L);
entity.setCreatorIdString("sajid");
entity.setNote(System.currentTimeMillis() + "");
entity.setQueueId(22);
entity.setQueueIdString("dddd");
String triggerId = "id: " + System.currentTimeMillis();
entity.setTriggerId(triggerId);
callRecordingScheduledProgramTriggerDAO.save(entity);
System.out.println("entity saved with id: " + triggerId );
throw new RuntimeException();
}
NOTE: the code works as expected when using DatasourceTransactionManager
UPDATE - 2:
Ok I have found the root cause of the problem. Thanks to Espen.
My entity manager configuration was like this(copied from spring pet-clinic app):
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceXmlLocation"
value="classpath:/persistence-test.xml" />
<property name="persistenceProvider">
<bean class="org.hibernate.ejb.HibernatePersistence" />
</property>
</bean>
Then I changed it to like this:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation"
value="classpath:/persistence-test.xml" />
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
</bean>
</property>
</bean>
Now everything seems to be working! Can anyone explain the difference between these two approach ?
It's possible to mix JPA and JDBC code in the same transaction using the JpaTransactionManager.
A snippet from Spring 3's JavaDoc:
This transaction manager also supports
direct DataSource access within a
transaction (i.e. plain JDBC code
working with the same DataSource).
This allows for mixing services which
access JPA and services which use
plain JDBC (without being aware of
JPA)!
You should be aware though that JPA caches the queries and executes all of them at the end of a transaction. So if you want to persist some data inside a transaction with JPA and then retrieve the data with JDBC, it will not work without explicitely flushing the JPA's persistence context before you attempt to retreive it with JDBC code.
A code example that asserts with JDBC code that the JPA code deleted a row inside a transaction:
#Test
#Transactional
#Rollback(false)
public void testDeleteCoffeeType() {
CoffeeType coffeeType = coffeeTypeDao.findCoffeeType(4L);
final String caffeForte = coffeeType.getName();
coffeeTypeDao.deleteCoffeeType(coffeeType);
entityManager.flush();
int rowsFoundWithCaffeForte = jdbcTemplate
.queryForInt("SELECT COUNT(*) FROM COFFEE_TYPES where NAME = ?",
caffeForte);
assertEquals(0, rowsFoundWithCaffeForte);
}
And if you prefer to use the JpaTemplate class, just replace the entityManager.flush() with jpaTemplate.flush();
In response to Sajids' comment:
With Spring you can configure a transaction manager that supports both JPA and JDBC like this:
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Transaction manager -->
<bean id="transactionManager" class="org.springframework.orm.jpa
.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
and Annotation-Driven version
#Bean
public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(emf);
return jpaTransactionManager;
}
In order to make it work, the JDBC queries must be executed with the JdbcTemplate or the SimpleJdbcTemplate class. In your case with the DAO that extends the SimpleJdbcDaoSupport, you should use the getSimpleJdbcTemplate(..) method.
And finally to let two DAO methods participate in the same transaction, call both DAO methods from a service class metho annotated with #Transactional. With the <tx:annotation-driven> element in your config, Spring will handle the transaction for you with the given transaction manager.
On the business layer:
public class ServiceClass {..
#Transactional
public void updateDatabase(..) {
jpaDao.remove(..);
jdbcDao.insert(..);
}
}
Edit 2:
Then something is wrong. It works for me exactly as specified in the Javadoc.
Does your entity manager has a datasource property like my bean below? It will only work as long you're injecting the same datasource into the entity manager and your extended JpaDaoSupport classes.
<bean id="entityManagerFactoryWithExternalDataSoure" primary="true"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor
.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<value>
hibernate.format_sql=true
</value>
</property>
</bean>
I've not really worked this out in detail yet as I've not mixed both JDBC and JPA but if you get your JDBC connection for an XA datasource then they are JTA transaction. So if you run your code in Stateless session bean for example with transaction turned on, then you automatically get both your Entities and JDBC managed by JTA.
EDIT
Here is an example code from Servlet
private #Resource DataSource xaDatasource;
private #Resource UserTransaction utx;
private #PersistenceUnit EntityManagerFactory factory;
public void doGet(HttpServletRequest req, HttpServletResponse res) ... {
utx.begin();
//Everything below this will be in JTA
Connection conn = xaDatasource.getConnection();
EntityManager mgr = factory.createEntityManager();
//Do your stuff
...
utx.commit();
}
Disclaimer: Code not tested.
Just realize this is not Spring but I'll leave it up anyway

Categories

Resources