2012-09-14 23 views
11

... sin tener que leer y analizar el persistence.xmlCómo recuperar la fuente de datos utilizada por una unidad de persistencia mediante programación

que puede recuperar el nombre de la unidad de persistencia de un EntityManager utilizando el properties of it's factory. Puedo recuperar las fuentes de datos disponibles usando el jboss-as-controller-client. Pero no he encontrado ninguna API que me dé la fuente de datos de un particular EntityManager.

Un String con un nombre sería suficiente.

Gracias

estoy trabajando con Hibernate 4.0.1.Final sobre JPA 2 en una JBoss 7.1.1.Final.

EDITAR: y me gustaría evitar pasar de JPA a Hibernate API si es posible.

EDITAR: La solución de Augusto funcionó, tengo algunas notas sobre los detalles: La fundición de la EM no funcionó debido a un ClassCastException :(org.jboss.as.jpa.container.TransactionScopedEntityManager cannot be cast to org.hibernate.ejb.EntityManagerImpl), pero funcionó para la fábrica recuperada. Así que omití el paso 1.

Tampoco pude encontrar una manera de recuperar el nombre de la fuente de datos de la instancia. Así que tuve que contentarme con el nombre de catálogo: connectionProvider.getConnection().getCatalog();

Respuesta

14

es necesario:

  1. tire la EntityManager a EntityManagerImpl (la implementación de Hibernate)
  2. llamada getFactory()
  3. tire la EntityManagerFactory a HibernateEntityManagerFactory
  4. llame al getSessionFactory() y vuélvala a SessionFactoryImpl
  5. llame al getConnectionProvider() y vuélvala a la implementación correcta. Puede ver las implementaciones here. Asumiré que es DatasourceConnectionProvider
  6. llame al getDataSource() y listo.

Lamentablemente, debe utilizar la API de Hibernate, ya que no hay forma de recuperar el DataSource con la API de JPA.

+0

Gracias, Augusto, parece prometedor. Todavía estoy luchando para salir del infierno de la dependencia, tratando de descubrir qué artefactos de hibernación realmente proporciona el jboss para referenciarlos en mi pom. Lo aceptaré una vez que vea la luz – kostja

+0

Funcionó, aunque con algunos caprichos. Ver la pregunta editada – kostja

+3

Otro ataque contra JPA en mi opinión ... Este proceso, aunque correcto, es mucho más complicado de lo necesario. – rtcarlson

8

Si lo que desea es el nombre de la fuente de datos y que el nombre de origen de datos se suministran por medio de la APP, que debe ser capaz de obtener esa información a través de:

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

o

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

dependiendo cómo definió la fuente de datos.

+1

No funciona para mí :(ambas consultas devuelven 'null'. ¿Tiene una fuente para esos nombres de propiedad? – kostja

+0

¿Una fuente? No estoy seguro de lo que quiere decir. La especificación JPA las define. ¿Es eso lo que quiere decir? –

+0

Sí, pensé que podía probar algunas otras propiedades. He encontrado el lugar - §9.4.3 Propiedades de la unidad de persistencia. Según lo he entendido, dado que no es necesario establecer estas propiedades, el proveedor puede no configurarlas. case for Hibernate? – kostja

4

Necesitaba hacer esto para ejecutar las migraciones de Flyway.Yo no era capaz de recuperar el origen de datos utilizando el método de Augusto, pero yo era capaz de recrear la fuente de datos mediante la recuperación de la URL, nombre de usuario & contraseña de las propiedades 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"); 
+0

genial, esta podría ser la actualización/solución prometida. – kostja

+0

No, no. El uso de un 'DataSource' diferente (incluso apuntando a la misma base de datos) puede conducir a problemas muy sutiles. –

5

En un ambiente de primavera se puede utilizar este :

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

@PersistenceContext 
EntityManager entityManager; 

public DataSource getDataSourceFromHibernateEntityManager() { 
    EntityManagerFactoryInfo info = (EntityManagerFactoryInfo) entityManager.getEntityManagerFactory(); 
    return info.getDataSource(); 
} 
2

Prueba esto:

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

Esto funcionó para mí. Tks –

1

estoy usando Hibernate 5.0.x

Así es como yo estoy haciendo una conexión de la agrupación persistencia:

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

El parámetro emf es estándar javax.persistence.EntityManagerFactory de APP, por lo general adquirida a nivel mundial usando:

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

o por inyección:

@PersistenceUnit(unitName="persistence-unit-name") 
EntityManagerFactory emf; 
Cuestiones relacionadas