Я разрабатываю webapp, который нуждается в доступе к двум различным серверам баз данных (H2 и Oracle). Контейнер Apache Tomee 1.5.1, и я использую стек Java EE с предоставленными в нем библиотеками (JSF, JPA, CDI, EJB и т.д.).
Я пытаюсь использовать два оператора сущности внутри транзакции XA для извлечения данных из базы данных Oracle и сохранять их в H2 после преобразования, но все запросы выполняются в отношении базы данных H2 независимо от того, какой менеджер объектов я использую, Любая помощь?
EDIT. Я обнаружил, что если я попытаюсь получить доступ к менеджерам сущностей в обратном порядке, они будут одинаковыми, но обращаются к Oracle. I.e.: Менеджеры сущностей остаются с первой доступной к базе данных.
EJB, где это происходит (вызов service.getFoo()
из JSF):
@Named
@Stateless
public class Service {
@Inject
@OracleDatabase
private EntityManager emOracle;
@Inject
@H2Database
private EntityManager emH2;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public List<Foo> getFoo() {
TypedQuery<Foo> q = emH2.createQuery(
"SELECT x FROM Foo f", Foo.class);
List<Foo> l = q.getResultList();
if (l == null || l.isEmpty()) {
update();
}
return q.getResultList();
}
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void update() {
// FAIL: This query executes against H2 with Oracle entity manager!
List<Object[]> l = emOracle.createNativeQuery("SELECT * FROM bar ").getResultList();
//more stuff...
}
}
Производитель ресурсов (CDI) для менеджеров объектов (где @H2Database и @OracleDatabase являются квалификаторами):
public class Resources {
@Produces
@PersistenceContext(unitName = "OraclePU")
@OracleDatabase
private EntityManager emOracle;
@Produces
@PersistenceContext(unitName = "H2PU")
@H2Database
private EntityManager emH2;
}
My peristence.xml выглядит так:
<?xml version="1.0" encoding="UTF-8"?>
<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="H2PU"
transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>H2DS</jta-data-source>
<class>my.app.h2.Foo</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
<persistence-unit name="OraclePU" transaction-type="JTA">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<jta-data-source>OracleDS</jta-data-source>
<class>my.app.oracle.Bar</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
</persistence>
И, наконец, источники данных внутри tomee.xml(в этом файле не настроены другие источники данных):
<Resource id="OracleDS" type="javax.sql.DataSource">
jdbcDriver = oracle.jdbc.xa.client.OracleXADataSource
jdbcUrl = jdbc:oracle:thin:@server:port:instance
jtaManaged = true
password = abcde
userName = user
</Resource>
<Resource id="H2DS" type="javax.sql.DataSource">
jdbcDriver=org.h2.jdbcx.JdbcDataSource
jdbcUrl=jdbc:h2:h2/db;AUTO_SERVER=TRUE
jtaManaged = true
password = edcba
userName = user
</Resource>