如何以编程方式检索持久性单元使用的数据源

kos*_*tja 19 hibernate jpa java-ee jpa-2.0 jboss7.x

...没有实际阅读和解析 persistence.xml

我可以EntityManager使用它的工厂属性检索一个持久性单元的名称.我可以使用jboss-as-controller-client检索可用的数据源.但我发现没有API会给我一个特定的数据源EntityManager.

一个String一个名字就足够了.

谢谢

我在JBoss 7.1.1.Final上使用Hibernate 4.0.1.Final而不是JPA 2.

编辑:我想尽可能避免从JPA转向Hibernate API.

编辑:奥古斯托的解决方案工作,我有一些关于细节的注释:EM的铸造因为ClassCastException:( org.jboss.as.jpa.container.TransactionScopedEntityManager cannot be cast to org.hibernate.ejb.EntityManagerImpl)而无效,但它适用于检索到的工厂.所以我省略了第1步.

我也找不到从实例中检索数据源名称的方法.所以我不得不满足于目录名称:connectionProvider.getConnection().getCatalog();

Aug*_*sto 19

你需要:

  1. 强制转换EntityManagerEntityManagerImpl(Hibernate实现)
  2. 呼叫 getFactory()
  3. EntityManagerFactoryHibernateEntityManagerFactory
  4. 打电话getSessionFactory()给他SessionFactoryImpl
  5. 调用getConnectionProvider()并将其转换为正确的实现.你可以在这里看到实现.我会假设它是一个DatasourceConnectionProvider
  6. 打电话getDataSource(),你完成了.

不幸的是,您必须使用Hibernate API,因为无法使用JPA API检索DataSource.

  • getConnectionProvider()现在似乎已从API中删除. (5认同)
  • 在我看来,对JPA的另一次打击......这个过程虽然正确但比必要的更复杂. (3认同)

小智 11

在Spring环境中,您可以使用:

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

@PersistenceContext
EntityManager entityManager;

public DataSource getDataSourceFromHibernateEntityManager() {
   EntityManagerFactoryInfo info = (EntityManagerFactoryInfo) entityManager.getEntityManagerFactory();
   return info.getDataSource();
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*ole 8

如果你只是想每JPA手段进行供给数据源和数据源名称的名称,你应该能够通过获得的信息:

entityManager.getEntityManagerFactory().getProperties().get( "javax.persistence.jtaDataSource" );
Run Code Online (Sandbox Code Playgroud)

要么

entityManager.getEntityManagerFactory().getProperties().get( "javax.persistence.nonJtaDataSource" );
Run Code Online (Sandbox Code Playgroud)

取决于您如何定义数据源.

  • 这个属性在Hibernate中工作(我用Hibernate 4.1试过):`entityManager.getEntityManagerFactory().getProperties().get("hibernate.connection.datasource");` (3认同)

You*_*ess 5

我正在使用 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);
    }
Run Code Online (Sandbox Code Playgroud)

你需要的只是将 entityManager.getEntityManagerFactory() 传递给这个方法(就我而言,我有多个工厂。然后我可以在需要时使用这个方法来获取其中任何一个的数据源)。