...without actually reading and parsing the persistence.xml
I can retrieve the name of the persistence unit of an EntityManager using the p
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.
You need to:
EntityManager to EntityManagerImpl (the Hibernate implementation)getFactory()EntityManagerFactory to HibernateEntityManagerFactorygetSessionFactory() and cast it to SessionFactoryImplgetConnectionProvider() and cast it to the correct implementation. You can see the implementations here. I'll assume that it's a DatasourceConnectionProvidergetDataSource() and you're done.Unfortunately, you must use the Hibernate API, as there's no way to retrieve the DataSource using the JPA API.
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");
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).
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();
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;