Reputation: 61578
...without actually reading and parsing the persistence.xml
I can retrieve the name of the persistence unit of an EntityManager
using the properties of it's factory. I can retrieve the available datasources using the jboss-as-controller-client. But I have found no API that would give me the datasource of a particular EntityManager
.
A String
with a name would be enough.
Thank you
I am working with Hibernate 4.0.1.Final over JPA 2 on a JBoss 7.1.1.Final.
EDIT: and I would like to avoid straying from JPA to Hibernate APIs if possible.
EDIT : Augusto's solution worked, I have some notes on details: The casting of the EM didn't work because of a ClassCastException
:(org.jboss.as.jpa.container.TransactionScopedEntityManager cannot be cast to org.hibernate.ejb.EntityManagerImpl
), but it worked for the retrieved factory. So I omitted step 1.
I also could not find a way to retrieve the name of the datasource from the instance. So I had to content myself with the catalog name: connectionProvider.getConnection().getCatalog();
Upvotes: 27
Views: 67207
Reputation: 181
I tried passing EntityfactoryBeanFactory name in PersistenceContext as unitName and it worked.
Below is an example.
@Configuration
@EnableJpaRepositories(
basePackages = "com.example.user.repository",
entityManagerFactoryRef = "userEntityManagerFactory",
dataSourceRef = "userDataSource",
transactionManagerRef = "userTransactionManager"
)
public class UserDatasourceConfiguration {
// Primary data source configuration
@Primary
@Bean(name = "userDataSource")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create()
.build();
}
// Configuration properties for the primary data source
@Primary
@Bean(name = "userProperties")
@ConfigurationProperties("spring.datasource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
// EntityManagerFactory for the primary data source
@Primary
@Bean(name = "userEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder builder,
DataSource dataSource) {
return builder
.dataSource(dataSource)
.packages("com.example.user.model")
.persistenceUnit("user")
.build();
}
}
Create UserService class and use PersistenceContext.
class UserService {
@PersistenceContext(unitName="userEntityManagerFactory")
EntityManager entityManager;
}
It worked for me. I had two different data source.
Upvotes: 0
Reputation: 1210
in SpringBoot environment you can use the following:
@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";
}
Upvotes: 1
Reputation: 601
DataSource dataSource = (DataSource)
em.getEntityManagerFactory().getProperties()
.get(org.hibernate.cfg.AvailableSettings.JPA_JTA_DATASOURCE);
You can retrieve datasoure with hibernate. Tested with Hibernate 5.3
Upvotes: 1
Reputation: 29
Here's what helped me. I use HikariCP but I don't think it matters.
Basically what needs to be done is
org.hibernate.engine.jdbc.connections.spi.ConnectionProvider
classjavax.sql.DataSource
.Service registry can be retrieved from EntityManager
((SessionImpl) em).getFactory().getServiceRegistry()
or from EntityManagerFactory directly
((SessionFactoryImpl) entityManagerFactory).getServiceRegistry()
Upvotes: -1
Reputation: 2080
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).
Upvotes: 10
Reputation: 2237
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;
Upvotes: 3
Reputation: 6525
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();
Upvotes: 4
Reputation: 201
In a Spring environment you can use this:
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
...
@PersistenceContext
EntityManager entityManager;
public DataSource getDataSourceFromHibernateEntityManager() {
EntityManagerFactoryInfo info = (EntityManagerFactoryInfo) entityManager.getEntityManagerFactory();
return info.getDataSource();
}
Upvotes: 20
Reputation: 30007
You need to:
EntityManager
to EntityManagerImpl
(the Hibernate implementation)getFactory()
EntityManagerFactory
to HibernateEntityManagerFactory
getSessionFactory()
and cast it to SessionFactoryImpl
getConnectionProvider()
and cast it to the correct implementation. You can see the implementations here. I'll assume that it's a DatasourceConnectionProvider
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.
Upvotes: 23
Reputation: 9443
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.
Upvotes: 9