24

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

EntityManager我可以使用它的工厂的属性来检索持久性单元的名称。我可以使用jboss-as-controller-client检索可用的数据源。但是我发现没有任何 API 可以为我提供特定的数据源EntityManager

一个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();

4

10 回答 10

22

你需要:

  1. 转换EntityManagerEntityManagerImpl(Hibernate 实现)
  2. 称呼getFactory()
  3. 投到EntityManagerFactory_HibernateEntityManagerFactory
  4. 调用getSessionFactory()并将其转换为SessionFactoryImpl
  5. 调用getConnectionProvider()并将其转换为正确的实现。您可以在此处查看实现。我会假设这是一个DatasourceConnectionProvider
  6. 打电话getDataSource(),你就完成了。

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

于 2012-09-14T12:05:02.520 回答
16

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

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

@PersistenceContext
EntityManager entityManager;

public DataSource getDataSourceFromHibernateEntityManager() {
   EntityManagerFactoryInfo info = (EntityManagerFactoryInfo) entityManager.getEntityManagerFactory();
   return info.getDataSource();
}
于 2014-11-04T22:51:10.017 回答
8

如果您只想要数据源的名称并且该数据源名称是根据 JPA 提供的,您应该能够通过以下方式获取该信息:

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

或者

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

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

于 2013-03-28T13:41:18.183 回答
6

我正在使用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() 传递给此方法(就我而言,我有多个工厂。然后我可以在需要时使用此方法获取其中任何一个的数据源)。

于 2018-11-14T18:14:56.520 回答
4

我需要这样做才能运行 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");
于 2013-10-17T16:30:58.383 回答
3

尝试这个 :

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();
于 2015-08-26T07:04:02.890 回答
2

我正在使用休眠 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;
于 2016-01-07T09:10:24.947 回答
1
DataSource dataSource = (DataSource) 
em.getEntityManagerFactory().getProperties()
            .get(org.hibernate.cfg.AvailableSettings.JPA_JTA_DATASOURCE);

您可以使用休眠检索数据源。使用休眠 5.3 测试

于 2020-01-14T22:09:09.800 回答
1

在 SpringBoot 环境中,您可以使用以下内容:

@PersistenceContext
EntityManager entityManager;

private HikariDataSource getDataSourceFromHibernateEntityManager() {
    EntityManagerFactoryInfo info = (EntityManagerFactoryInfo) entityManager.getEntityManagerFactory();
    return (HikariDataSource) info.getDataSource();
}

public String getDataSourceProperties() {
    HikariDataSource dataSource = getDataSourceFromHibernateEntityManager();
    return "DataSource properties:" +
            "URL: " + dataSource.getJdbcUrl() + "\n" +
            "Default Schema: " + dataSource.getPoolName() + "\n" +
            "Driver Class Name: " + dataSource.getDriverClassName() + "\n" +
            "Username: " + dataSource.getUsername() + "\n";
}
于 2020-09-28T12:02:44.133 回答
-1

这对我有帮助。我使用 HikariCP,但我认为这并不重要。

基本上需要做的是

  1. 查找服务注册表
  2. org.hibernate.engine.jdbc.connections.spi.ConnectionProvider按类获得服务
  3. 将其解包到javax.sql.DataSource.

可以从 EntityManager 检索服务注册表

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

或直接从 EntityManagerFactory

((SessionFactoryImpl) entityManagerFactory).getServiceRegistry()
于 2018-11-21T19:33:26.850 回答