Я пытаюсь создать приложение, которое может сохранять как JPA, так и Mongo объекты, используя Spring boot.Я реализовал MongoResourceManager и JPAResourceManager с помощью XAResource.JPAResourceManager не сохранит данные, пока не будет явно вызван entityManager.flush ().
JTA config
<bean class="org.springframework.transaction.jta.JtaTransactionManager"
id="transactionManager" lazy-init="true">
<property name="transactionManager">
<bean
class="com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple" />
</property>
<property name="userTransaction">
<bean class="com.arjuna.ats.jta.UserTransaction" factory-method="userTransaction" />
</property>
</bean>
JPA Config
<tx:annotation-driven proxy-target-class="true" />
<bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="oracleEMForacle1" lazy-init="true" primary="true">
<property name="jpaProperties">
<props>
<prop key="hibernate.format_sql">true</prop>
<prop key ="hibernate.jdbc.batch_size">50</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle12cDialect</prop>
<prop key="hibernate.transaction.jta.platform">org.hibernate.engine.transaction.jta.platform.internal.JBossStandAloneJtaPlatform
</prop>
<prop key="hibernate.flushMode">commit</prop>
<prop key="hibernate.use_sql_comments">true</prop>
</props>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.Oracle12cDialect" />
<property name="generateDdl" value="true" />
<property name="showSql" value="false" />
</bean>
</property>
<property name="jtaDataSource">
<bean class="org.apache.commons.dbcp2.BasicDataSource">
<property name="connectionProperties"
value="password=${password};user=${username}"></property>
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="${url}" />
</bean>
</property>
<property name="packagesToScan">
<array>
<value>com.test.jpa.jpaentity</value>
</array>
</property>
</bean>
JPAResourceManager
public class JpaResourceManager extends ResourceManagerCommon implements XAResource
{
private static final XLogger logger = XLogger.getXLogger(JpaResourceManager.class);
private EntityManager em;
public JpaResourceManager(PersistanceAgent<EntityManagerFactory> persistanceAgent) {
super(persistanceAgent);
}
/**
* EntityManagerFactory will be retrieved from ConfigurableApplicationContext
*/
@Override
public void start(Xid xid, int i) throws XAException {
EntityManagerFactory emf = this.persistanceAgent.getDataSource();
this.em = emf.createEntityManager();
}
@Override
public int prepare(Xid xid) throws XAException {
try {
ITxArea txArea = getTxArea();
em.joinTransaction();
for (EntityWithOperation entity : txArea.values()) {
em.persist(entity);
}
//this.em.flush(); // Explicitly calling flush
} catch (Exception e) {
throw new XAException(XAException.XAER_RMERR);
}
return XA_OK;
}
@Override
public void commit(Xid xid, boolean isLocalTransaction) throws XAException {
if (em.isOpen()) {
em.clear();
em.close();
}
}
@Override
public Xid[] recover(int i) throws XAException {
return new Xid[0];
}
@Override
public void rollback(Xid xid) throws XAException {
logger.warn("JPA ResourceManager ROLLBACK called..");
closeEntityManager(this.em);
}
@Override
public boolean setTransactionTimeout(int i) throws XAException {
return false;
}
@Override
public void end(Xid xid, int i) throws XAException {
}
@Override
public void forget(Xid xid) throws XAException {
}
@Override
public int getTransactionTimeout() throws XAException {
return 0;
}
@Override
public boolean isSameRM(XAResource xaResource) throws XAException {
return false;
}
}