... sans réellement lire et analyser le persistence.xml
Je peux récupérer le nom de l'unité de persistance d'une EntityManager
en utilisant les propriétés de sa fabrique . Je peux récupérer les sources de données disponibles en utilisant le jboss-as-controller-client . Mais je n'ai trouvé aucune API qui me donnerait la source de données d'un EntityManager
particulier.
Une String
avec un nom suffirait.
Je vous remercie
Je travaille avec Hibernate 4.0.1.Final sur JPA 2 sur un JBoss 7.1.1.Final.
EDIT: et je voudrais éviter, si possible, de s’éloigner des API JPA vers Hibernate.
EDIT: La solution d’Augusto a fonctionné, j’ai quelques remarques sur les détails: Le casting de l’EM n’a pas fonctionné à cause d’une ClassCastException
: (org.jboss.as.jpa.container.TransactionScopedEntityManager cannot be cast to org.hibernate.ejb.EntityManagerImpl
), mais cela a fonctionné pour l’usine récupérée. J'ai donc omis l'étape 1.
Je ne pouvais pas non plus trouver un moyen de récupérer le nom de la source de données à partir de l'instance. Je devais donc me contenter du nom du catalogue: connectionProvider.getConnection().getCatalog();
Tu dois:
EntityManager
en EntityManagerImpl
(l'implémentation d'Hibernate)getFactory()
EntityManagerFactory
à HibernateEntityManagerFactory
getSessionFactory()
et transformez-le en SessionFactoryImpl
getConnectionProvider()
et convertissez-le en implémentation correcte. Vous pouvez voir les implémentations ici . Je suppose que c'est une DatasourceConnectionProvider
getDataSource()
et vous avez terminé.Malheureusement, vous devez utiliser l'API Hibernate, car il n'existe aucun moyen de récupérer le DataSource à l'aide de l'API JPA.
Si vous voulez juste le nom de la source de données et que le nom de la source de données a été fourni par JPA, vous devriez pouvoir obtenir ces informations via:
entityManager.getEntityManagerFactory().getProperties().get( "javax.persistence.jtaDataSource" );
ou
entityManager.getEntityManagerFactory().getProperties().get( "javax.persistence.nonJtaDataSource" );
en fonction de la définition de la source de données.
Dans un environnement de printemps, vous pouvez utiliser ceci:
import org.springframework.orm.jpa.EntityManagerFactoryInfo;
...
@PersistenceContext
EntityManager entityManager;
public DataSource getDataSourceFromHibernateEntityManager() {
EntityManagerFactoryInfo info = (EntityManagerFactoryInfo) entityManager.getEntityManagerFactory();
return info.getDataSource();
}
Je devais le faire pour pouvoir exécuter les migrations Flyway. Je n'ai pas pu récupérer la source de données à l'aide de la méthode d'Augusto, mais j'ai pu recréer la source de données en récupérant l'url, le nom d'utilisateur et le mot de passe à partir des propriétés SessionFactory:
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");
Essaye ça :
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();
J'utilise Hibernate 5.0.x
Voici comment je reçois une connexion du pool de persistance:
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();
}
Le paramètre emf
est le javax.persistence.EntityManagerFactory
standard de JPA, généralement acquis de manière globale à l'aide de:
emf = Persistence.createEntityManagerFactory("persistence-unit-name");
ou par injection:
@PersistenceUnit(unitName="persistence-unit-name")
EntityManagerFactory emf;
Voici ce qui m'a aidé. J'utilise HikariCP mais je ne pense pas que cela compte.
Fondamentalement, ce qui doit être fait est
org.hibernate.engine.jdbc.connections.spi.ConnectionProvider
classejavax.sql.DataSource
.Le registre de service peut être récupéré à partir de EntityManager
((SessionImpl) em).getFactory().getServiceRegistry()
ou de EntityManagerFactory directement
((SessionFactoryImpl) entityManagerFactory).getServiceRegistry()
J'utilise hibernate 5.2.10.Final et ce qui suit a fonctionné pour moi:
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);
}
Ce que vous avez besoin est simplement de passer entityManager.getEntityManagerFactory () à cette méthode (dans mon cas, j'ai plusieurs usines. Ensuite, je peux utiliser cette méthode pour obtenir la source de données de l'une d'elles en cas de besoin).