Warum unterschiedliche Persistenzeinheiten mit getrennten Datenquellen die gleiche Datenquelle abfragen?

Ich bin die Entwicklung einer webapp, die benötigt Zugriff auf zwei verschiedene Datenbank-Server (H2 und Oracle).
Der container ist eine Apache Tomee 1.5.1 und ich bin mit dem Java EE stack mit Bibliotheken (JSF, JPA, CDI, EJB, etc.).

Ich versuche, zwei entity-Manager innerhalb einer XA-Transaktion zum extrahieren von Daten aus der Oracle Datenbank und speichern Sie es in der H2 nach der Umwandlung, ABER alle Abfragen ausgeführt werden, die H2-Datenbank egal den entity-manager, die ich benutze. Keine Hilfe?

BEARBEITEN: ich fand, dass wenn ich versuche, Zugriff auf den entity-Manager in der umgekehrten Reihenfolge, Sie Verhalten ist das gleiche, aber den Zugriff auf Oracle. I. e.: der entity-Manager bleiben mit der ersten Datenbank zugegriffen.

EJB-wo dies geschieht (Aufruf service.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...
    }
}

Die Ressource Produzent (CDI) für den entity-Manager (wo @H2Database und @OracleDatabase sind Qualifier):

public class Resources {
    @Produces
    @PersistenceContext(unitName = "OraclePU")
    @OracleDatabase
    private EntityManager emOracle;

    @Produces
    @PersistenceContext(unitName = "H2PU")
    @H2Database
    private EntityManager emH2;
}

Meine peristence.xml sieht wie folgt aus:

<?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 Daten-Quellen innerhalb tomee.xml (es gibt keine anderen Datenquellen konfiguriert, die in dieser Datei):

<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>

InformationsquelleAutor der Frage |

Schreibe einen Kommentar