web-dev-qa-db-ja.com

プログラムで永続性ユニットによって使用されるデータソースを取得する方法

...実際に_persistence.xml_を読み取って解析することなく

そのファクトリのプロパティ を使用して、EntityManagerの永続性ユニットの名前を取得できます。 jboss-as-controller-client を使用して、使用可能なデータソースを取得できます。しかし、特定のEntityManagerのデータソースを提供するAPIは見つかりませんでした。

名前付きのStringで十分です。

ありがとうございました

JBoss 7.1.1.FinalでJPA 2よりもHibernate 4.0.1.Finalを使用しています。

編集:そして、可能であればJPAからHibernate APIに迷うのを避けたいです。

編集:アウグストの解決策はうまくいきました、私は詳細についていくつかのメモがあります:EMのキャスティングはClassCastException:(_org.jboss.as.jpa.container.TransactionScopedEntityManager cannot be cast to org.hibernate.ejb.EntityManagerImpl_)のためにうまくいきませんでしたが、取得したファクトリではうまくいきました。したがって、ステップ1を省略しました。

また、インスタンスからデータソースの名前を取得する方法も見つかりませんでした。だから私はカタログ名で自分自身を満足させなければなりませんでした:connectionProvider.getConnection().getCatalog();

20
kostja

必要がある:

  1. EntityManagerEntityManagerImplにキャストします(Hibernate実装)
  2. 呼び出しgetFactory()
  3. EntityManagerFactoryHibernateEntityManagerFactoryにキャストします
  4. getSessionFactory()を呼び出してSessionFactoryImplにキャストします
  5. getConnectionProvider()を呼び出して、正しい実装にキャストします。実装 ここ を確認できます。 DatasourceConnectionProviderだと思います
  6. getDataSource()を呼び出すと、完了です。

残念ながら、JPA APIを使用してDataSourceを取得する方法がないため、Hibernate APIを使用する必要があります。

19
Augusto

Spring環境ではこれを使用できます:

import org.springframework.orm.jpa.EntityManagerFactoryInfo;
...

@PersistenceContext
EntityManager entityManager;

public DataSource getDataSourceFromHibernateEntityManager() {
   EntityManagerFactoryInfo info = (EntityManagerFactoryInfo) entityManager.getEntityManagerFactory();
   return info.getDataSource();
}
9
Markus Umefjord

データソースの名前だけが必要で、そのデータソース名がJPA手段ごとに提供されている場合は、次の方法で情報を取得できます。

entityManager.getEntityManagerFactory().getProperties().get( "javax.persistence.jtaDataSource" );

または

entityManager.getEntityManagerFactory().getProperties().get( "javax.persistence.nonJtaDataSource" );

データソースの定義方法によって異なります。

8
Steve Ebersole

Flyway移行を実行するには、これを行う必要がありました。 Augustoのメソッドを使用してDataSourceを取得することはできませんでしたが、SessionFactoryプロパティからURL、ユーザー名、およびパスワードを取得することにより、データソースを再作成することができました。

SessionFactory sessionFactory = ((HibernateEntityManagerFactory) entityManagerFactory).getSessionFactory();
Properties properties = ((SessionFactoryImpl) sessionFactory).getProperties();
String url = (String) properties.get("hibernate.connection.url");
String username = (String) properties.get("hibernate.connection.username");
String password = (String) properties.get("hibernate.connection.password");
4
shangxiao

これを試して :

Session s = (Session) getEntityManager().getDelegate();
org.hibernate.SessionFactory sessionFactory=s.getSessionFactory();
ConnectionProvider cp=((SessionFactoryImpl)sessionFactory).getConnectionProvider();Connection connection=cp.getConnection();
DatabaseMetaData dbmetadata= connection.getMetaData();
String dtsource=dbmetadata.getUserName();
3
JDGuide

Hibernate 5.0.xを使用しています

これは、永続プールから接続を取得する方法です。

import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.jpa.internal.EntityManagerFactoryImpl;

public Connection getConnection(EntityManagerFactory emf) throws SQLException
{
    final EntityManagerFactoryImpl hibernateEmf = (EntityManagerFactoryImpl) emf;
    return hibernateEmf.getSessionFactory().getServiceRegistry().getService(ConnectionProvider.class).getConnection();
}

emfパラメータはJPAの標準javax.persistence.EntityManagerFactory、通常は以下を使用してグローバルに取得します:

emf = Persistence.createEntityManagerFactory("persistence-unit-name");

または注射によって:

@PersistenceUnit(unitName="persistence-unit-name")
EntityManagerFactory emf;
2
Zach-M

私はhibernate 5.2.10.Finalを使用していますが、以下がうまくいきました:

    import org.hibernate.SessionFactory;
    import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
    import javax.persistence.EntityManagerFactory;
    import javax.sql.DataSource;
    //...
    public static DataSource getDataSource(EntityManagerFactory entityManagerFactory) {
    ConnectionProvider cp = ((SessionFactory) entityManagerFactory).getSessionFactoryOptions()
            .getServiceRegistry()
            .getService(ConnectionProvider.class);
    return cp.unwrap(DataSource.class);
    }

必要なのは、entityManager.getEntityManagerFactory()をこのメソッドに渡すことだけです(私の場合、複数のファクトリがあります。その後、このメソッドを使用して、必要なときにこれらのいずれかのデータソースを取得できます)。

1
Youness
DataSource dataSource = (DataSource) 
em.getEntityManagerFactory().getProperties()
            .get(org.hibernate.cfg.AvailableSettings.JPA_JTA_DATASOURCE);

Hibernateでデータソースを取得できます。 Hibernate 5.3でテスト済み

0
László Tóth

ここで私を助けました。 HikariCPを使っていますが、大したことはないと思います。

基本的に行う必要があるのは

  1. サービスレジストリを見つける
  2. org.hibernate.engine.jdbc.connections.spi.ConnectionProviderクラスでサービスを受ける
  3. javax.sql.DataSourceに展開します。

EntityManagerからサービスレジストリを取得できます

((SessionImpl) em).getFactory().getServiceRegistry()

またはEntityManagerFactoryから直接

((SessionFactoryImpl) entityManagerFactory).getServiceRegistry()
0
Mikie Mike