4

複数のスキーマを持つデータベースがあるため、複数のスキーマを持つpersistence.xmlファイルがあります<persistence-unit />(名前は01、02、...)。

問題: いくつかのユーザー基準の EntityManager 動的関数を作成したいと考えています。

私は2つのケースをテストしました。

最初のケース:基本的に、このコードをテストしました (ステートレス EJB 内):

String criteria = "01";     
EntityManagerFactory emf = Persistence.createEntityManagerFactory(criteria);
EntityManager em = emf.createEntityManager();

Joueur joueur = new Joueur(); // Joueur is an Entity
joueur.setPseudo("olivier");

em.persist(joueur);

しかし、私は例外を受け取りました:

原因: 例外 [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: org.postgresql.util.PSQLException: ERREUR: la transaction est annulée, les commandes sont ignorées jusqu'à la fin du bloc de la transaction

(いくつかの Stackoverflow の投稿の助けを借りて)、私の EntityManager は、コンテナーによって注入されなかったという事実のために、私のトランザクション コンテキストに「リンク」されていないと思いました。

2番目のケース:したがって、私は注入を使用しました:

@PersistenceContext(unitName="00")
private EntityManager em00;

@PersistenceContext(unitName="01")
private EntityManager em01;

私の機能のコード:

String criteria = "01";
EntityManager em = getEm(criteria);
...

および getEm() メソッド:

private EntityManager getEm(String criteria){

    if (criteria == "00")
        return em00;
    else if (criteria == "01")
        return em01;

    return null;
}

問題ありません。問題はありませんが、永続ユニットを持っているのと同じ数の EntityManagers を注入する必要があります。

  • スキーマが 50 個ある場合のコストはどうなりますか?
  • エンティティマネージャを動的に管理する方法はありますか? (1 EntityManger のみ)
  • 使用しない場合でも、スキーマごとに 1 つの EntityManager を作成する必要がある場合、可能な限り最小限のリソースを消費するようにコードを改善するにはどうすればよいですか?

アドバイスやフィードバックをありがとう

編集 :

私の構成ファイル:

Persistence.xml :

<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="00" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/sim/00</jta-data-source>
        <mapping-file>orm_00_beta.xml</mapping-file>
        <class>com.sim.entities.Joueur</class>      
        <properties>
            <property name="eclipselink.ddl-generation" value="create-tables" />
        </properties>       
    </persistence-unit>

    <persistence-unit name="01" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/sim/01</jta-data-source>
        <mapping-file>orm_01_beta2.xml</mapping-file>
        <class>com.sim.entities.Joueur</class>
        <properties>
            <property name="eclipselink.ddl-generation" value="create-tables" />
        </properties>
    </persistence-unit>

</persistence>

orm_00_beta.xml :

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0">

<persistence-unit-metadata>
    <persistence-unit-defaults>        
        <schema>beta</schema>
    </persistence-unit-defaults>
</persistence-unit-metadata>   

orm_01_beta2.xml :

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0">

<persistence-unit-metadata>
    <persistence-unit-defaults>        
        <schema>beta2</schema>
    </persistence-unit-defaults>
</persistence-unit-metadata>   

4

2 に答える 2

2

アプリケーション管理の持続性ユニットを使用する場合は、使用しているアプリケーション サーバーに「eclipselink.target-server」を設定する必要があります (一部のサーバーはこれを自動的に設定し、コンテナー管理の持続性ユニットを使用します)。次に、EntityManager は、作成時にアクティブな JTA トランザクションとバインドします。JTA トランザクションの開始前に EntityManager を作成すると、joinTransaction() を使用できます。

問題が解決しない場合は、使用しているサーバーと完全な例外スタック トレースを含めてください。

多数のスキーマがある場合は、EclipseLink マルチテナント サポートの使用を検討できます。これにより、各テナントが独自のスキーマを持つことができます。

http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/a_multitenant.htm#BABEGBIJ

于 2012-11-21T14:43:09.887 に答える
1

通常、50 個のスキーマはありません。通常、EJB コンテナーには既に開いている接続のプールがあり、注入の準備ができているため、注入のコストについて心配する必要はありません。したがって、オーバーヘッドは非常に小さいです。

AFAIK、JPAは動的エンティティマネージャーを許可していません。

リソースに関心がある場合は、EclipseLink の使用を避けることをお勧めします (私は EclipseLink + EJB で非常に悪い経験をしました)。

少し最適化するために、ここではファクトリ パターンを使用します。EntityManager を提供する Bean を作成します。複数の PersistenceContext を注入する代わりに、次のようなメソッドで 1 つの注入を行います。

EntityManager getEntityManager(String schemaId) {...}

別のオプションは、すべての注入を AbstractBean に移動することです。他のすべての Bean は AbstractBean から継承します。

于 2012-11-21T13:42:08.870 に答える