8

標準のEJB3では、エンティティマネージャを挿入するときに、永続性ユニット(データソースを参照)がアノテーションにハードコードされます:(またはxmlファイル)

@PersistenceContext(unitName = "myunit")
private EntityManager entityManager;

エンティティマネージャーを使用する方法はありますが、実行時に名前でデータソースを選択する方法はありますか?

4

4 に答える 4

5

EclipseLinkを使用して、アプリサーバーで構成されたデータソースを設定できます。

import org.eclipse.persistence.config.PersistenceUnitProperties;
...


....
Map props = new HashMap();  
props.put(PersistenceUnitProperties.JTA_DATASOURCE, "dataSource");  
EntityManagerFactory  emf = Persistence.createEntityManagerFactory("UNIT_NAME", props);
EntityManager em = emf.createEntityManager();

PU_NAMEファイルpersistence.xmlで使用される名前を参照します
dataSourceは、jdbcリソースのアプリサーバーで使用される名前を「jdbc/sample」として参照します

于 2012-02-16T16:16:10.967 に答える
2

可能です!私はそれを行い、JBoss AS と WebSphere で動作します。

拡張するカスタム永続化プロバイダーを使用します (永続化プロバイダー名を に設定するには、フィールドを変更するorg.hibernate.ejb.HibernatePersistence必要があります。これは一種の黒魔術ですが、機能します)。の持続性ユニットのタグにカスタム プロバイダが設定されており、カスタム プロバイダが に登録されていることを確認してください。private static finalorg.hibernate.ejb3.Ejb3Configuration.IMPLEMENTATION_NAMEpersistence.xml<provider>META-INF/services/javax.persistence.spi.PersistenceProvider

私のプロバイダーcreateContainerEntityManagerFactory(PersistenceUnitInfo,Map)は、Java EE コンテナーと呼ばれるメソッドをオーバーライドします (JTA データソースの場合ですが、非 JTA データソースでも簡単に実行できます)。

@Override
public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map) {

    // load the DataSource
    String newDataSourceName = ...; // any name you want
    DataSource ds = (DataSource)(new InitialContext().lookup(newDataSourceName));

    // modify the datasource
    try {
        try {
            // JBoss implementation (any maybe other Java EE vendors except IBM WebSphere)
            Method m = info.getClass().getDeclaredMethod("setJtaDataSource", DataSource.class);
            m.setAccessible(true);
            m.invoke(info, ds);

        } catch (NoSuchMethodException e) {
            // method does not exist (WebSphere?) => try the WebSphere way

            // set the datasource name
            Method m = info.getClass().getDeclaredMethod("setJtaDataSource", String.class);
            m.setAccessible(true);
            m.invoke(info, newDataSourceName);

            // do the lookup
            Method m2 = info.getClass().getDeclaredMethod("lookupJtaDataSource", String.class);
            m2.setAccessible(true);
            m2.invoke(info);
        }
    } catch (Throwable e) {
        throw new RuntimeException("could not change DataSource for "+info.getClass().getName());
    }

    // delegate the EMF creation
    return new HibernatePersistence().createContainerEntityManaferFactory(info, map);
}

これcreateEntityManagerFactory(String,Map)もオーバーライドされますが、はるかに単純です。

@Override
public EntityManagerFactory createEntityManagerFactory(String persistenceUnitInfo, Map map) {

    // change the datasource name
    String newDataSourceName = ...; // any name you want
    if (map==null) map = new HashMap();  
    map.put(HibernatePersistence.JTA_DATASOURCE, newDataSourceName);  

    // delegate the EMF creation
    return new HibernatePersistence().createEntityManaferFactory(persistenceUnitInfo, map);
}

ここではコア コードのみを記述したことに注意してください。実際、私の持続性プロバイダーには他にも多くの機能があります。

  • DataSource が稼働していることを確認します
  • JBoss または WebSphere のトランザクション マネージャーを設定する
  • メモリ使用量を抑えるために EMF をキャッシュする
  • メモリ使用量を減らすために Hibernate クエリ プラン キャッシュを再構成する
  • JMX Bean を登録します (複数の EAR が同じ持続性ユニット名を取得できるようにするため)
于 2013-11-07T08:29:04.447 に答える
2
  • persistence.xml で必要なデータ ソースと永続ユニットを構成します。
<persistence-unit name="UNIT_NAME" transaction-type="JTA">
      <provider>PERSISTENCE_PROVIDER</provider>
          <jta-data-source>java:DATA_SOURCE_NAME</jta-data-source>
</persistence-unit>

 -- other units  

実行時に、必要な永続ユニットのエンティティ マネージャーを構築できるようになりました。データ ソースごとに個別の持続性ユニットを作成します。

//---
EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnitName);
EntityManager em = emf.createEntityManager();
//---
  • それ以外の場合は、db-url、userName などのプロパティのマップを提供してファクトリを構築することもできます。
createEntityManagerFactory(persistenceUnitName,propertiesMap);

これにより、指定されたプロパティを使用して、指定された持続性ユニットの EntityManagerFactory が作成されて返されます。したがって、それに応じて実行時にプロパティを変更できます。

于 2011-03-12T04:43:39.470 に答える
1

の使用法を示したい

Persistence.createEntityManagerFactory(persistenceUnitName)

Nayan の回答で推奨されるものは、JPA 仕様 (JSR 317) によって次のように分類されます (「9.2 Java SE 環境でのブートストラップ」の脚注)。

「これらの Java SE ブートストラップ API の使用は、Java EE コンテナーでサポートされている場合がありますが、そのような使用のサポートは必須ではありません。」

したがって、これは EJB の標準的なソリューションではありません。とにかく、これがEclipseLinkで機能していることを確認できます。

注: これをコメントとして投稿することはまだ許可されていません。

于 2012-12-09T21:21:31.520 に答える