...実際に_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();
必要がある:
EntityManager
をEntityManagerImpl
にキャストします(Hibernate実装)getFactory()
EntityManagerFactory
をHibernateEntityManagerFactory
にキャストしますgetSessionFactory()
を呼び出してSessionFactoryImpl
にキャストしますgetConnectionProvider()
を呼び出して、正しい実装にキャストします。実装 ここ を確認できます。 DatasourceConnectionProvider
だと思いますgetDataSource()
を呼び出すと、完了です。残念ながら、JPA APIを使用してDataSourceを取得する方法がないため、Hibernate APIを使用する必要があります。
Spring環境ではこれを使用できます:
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
...
@PersistenceContext
EntityManager entityManager;
public DataSource getDataSourceFromHibernateEntityManager() {
EntityManagerFactoryInfo info = (EntityManagerFactoryInfo) entityManager.getEntityManagerFactory();
return info.getDataSource();
}
データソースの名前だけが必要で、そのデータソース名がJPA手段ごとに提供されている場合は、次の方法で情報を取得できます。
entityManager.getEntityManagerFactory().getProperties().get( "javax.persistence.jtaDataSource" );
または
entityManager.getEntityManagerFactory().getProperties().get( "javax.persistence.nonJtaDataSource" );
データソースの定義方法によって異なります。
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");
これを試して :
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();
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;
私は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()をこのメソッドに渡すことだけです(私の場合、複数のファクトリがあります。その後、このメソッドを使用して、必要なときにこれらのいずれかのデータソースを取得できます)。
DataSource dataSource = (DataSource)
em.getEntityManagerFactory().getProperties()
.get(org.hibernate.cfg.AvailableSettings.JPA_JTA_DATASOURCE);
Hibernateでデータソースを取得できます。 Hibernate 5.3でテスト済み
ここで私を助けました。 HikariCPを使っていますが、大したことはないと思います。
基本的に行う必要があるのは
org.hibernate.engine.jdbc.connections.spi.ConnectionProvider
クラスでサービスを受けるjavax.sql.DataSource
に展開します。EntityManagerからサービスレジストリを取得できます
((SessionImpl) em).getFactory().getServiceRegistry()
またはEntityManagerFactoryから直接
((SessionFactoryImpl) entityManagerFactory).getServiceRegistry()