How to retrieve the datasource used by a persistence unit programmatically

后端 未结 10 1504
旧时难觅i
旧时难觅i 2020-12-07 23:05

...without actually reading and parsing the persistence.xml

I can retrieve the name of the persistence unit of an EntityManager using the p

相关标签:
10条回答
  • 2020-12-07 23:43

    If you just want the name of the datasource and that datasource name was supplied per JPA means, you should be able to get that information via:

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

    or

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

    depending on how you defined the datasource.

    0 讨论(0)
  • 2020-12-07 23:48

    You need to:

    1. cast the EntityManager to EntityManagerImpl (the Hibernate implementation)
    2. call getFactory()
    3. cast the EntityManagerFactory to HibernateEntityManagerFactory
    4. call getSessionFactory() and cast it to SessionFactoryImpl
    5. call getConnectionProvider() and cast it to the correct implementation. You can see the implementations here. I'll assume that it's a DatasourceConnectionProvider
    6. call getDataSource() and you're done.

    Unfortunately, you must use the Hibernate API, as there's no way to retrieve the DataSource using the JPA API.

    0 讨论(0)
  • 2020-12-07 23:50

    I needed to do this in order to run Flyway migrations. I wasn't able to retrieve the DataSource using Augusto's method, but I was able to recreate the data source by retrieving the url, username & password from the SessionFactory properties:

    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");
    
    0 讨论(0)
  • 2020-12-07 23:50

    I am using hibernate 5.2.10.Final and the following worked for me:

        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);
        }
    

    What you need is just to pass entityManager.getEntityManagerFactory() to this method (For my case, I have multiple factories. Then I can use this method to get the datasource for any of them when needed).

    0 讨论(0)
  • 2020-12-07 23:53

    Try this :

    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();
    
    0 讨论(0)
  • 2020-12-07 23:54

    I'm using Hibernate 5.0.x

    This is how I'm getting a connection from the persistence pool:

    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();
    }
    

    The emf parameter is JPA's standard javax.persistence.EntityManagerFactory, typically acquired globally using:

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

    or by injection:

    @PersistenceUnit(unitName="persistence-unit-name")
    EntityManagerFactory emf;
    
    0 讨论(0)
提交回复
热议问题