Warum fragen verschiedene Persistenzeinheiten mit getrennten Datenquellen dieselbe Datenquelle ab?
Ich entwickle eine Webapp, die Zugriff auf zwei verschiedene Datenbankserver (H2 und Oracle) benötigt. Der Container ist einApache Tomee 1.5.1 Ich verwende den Java EE-Stack mit den darin enthaltenen Bibliotheken (JSF, JPA, CDI, EJB usw.).
Ich versuche, zwei Entitätsmanager in einer XA-Transaktion zu verwenden, um Daten aus der Oracle-Datenbank zu extrahieren und sie nach der Transformation im H2 zu speichern, ABER alle Abfragen werden unabhängig vom verwendeten Entitätsmanager für die H2-Datenbank ausgeführt. Irgendeine Hilfe?
BEARBEITEN: Wenn ich versuche, in umgekehrter Reihenfolge auf die Entitätsmanager zuzugreifen, ist das Verhalten dasselbe, es wird jedoch auf Oracle zugegriffen. Das heißt, die Entity Manager bleiben bei der ersten Datenbank, auf die zugegriffen wurde.
Die EJB, in der dies geschieht (Aufrufservice.getFoo()
von 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...
}
}
Der Ressourcenproduzent (CDI) für die Entitätsmanager (wobei sich @ H2Database und @OracleDatabase befindenQualifikanten):
public class Resources {
@Produces
@PersistenceContext(unitName = "OraclePU")
@OracleDatabase
private EntityManager emOracle;
@Produces
@PersistenceContext(unitName = "H2PU")
@H2Database
private EntityManager emH2;
}
Meineperistence.xml sieht aus wie das:
<?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>
Und schließlich die darin enthaltenen Datenquellentomee.xml (In dieser Datei sind keine anderen Datenquellen konfiguriert):
<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>