En un bean de sesión sin estado se inyecta un EntityManager
pero me gustaría obtener un objeto Connection
para invocar un procedimiento DB. ¿Hay alguna solución a esto?Obtener un objeto de conexión JDBC de un Bean sin estado
Respuesta
Este será el código específico del proveedor de JPA. Normalmente esto se hace invocando unwrap()
en la clase EntityManager
.
Si está utilizando EclipseLink, el siguiente código (de la EclipseLink wiki) será útil (en el caso de que utilice una aplicación gestionados EntityManager):
APP 2,0
entityManager.getTransaction().begin();
java.sql.Connection connection = entityManager.unwrap(java.sql.Connection.class); // unwraps the Connection class.
...
entityManager.getTransaction().commit();
APP 1,0
entityManager.getTransaction().begin();
UnitOfWork unitOfWork = (UnitOfWork)((JpaEntityManager)entityManager.getDelegate()).getActiveSession();
unitOfWork.beginEarlyTransaction();
Accessor accessor = unitOfWork.getAccessor();
accessor.incrementCallCount(unitOfWork.getParent());
accessor.decrementCallCount();
java.sql.Connection connection = accessor.getConnection();
...
entityManager.getTransaction().commit();
Tenga en cuenta, que la solución proporcionada por JPA 2.0 fallará para Hibernate 3.6.5 con un PersistenceException
que contiene el mensaje
Hibernate no puede desenvolver interfaz java.sql.Connection
Utilice el código proporcionado por Skaffman a conseguir que funcione contra Hibernate (verificado para trabajar bajo 3.6.5 incluso para contextos de persistencia administrados por contenedor).
Sin embargo, el wiki de EclipseLink señala un poco de información útil: si está utilizando orígenes de datos administrados por JTA, debe inyectarlo usando la anotación @Resource
o recuperarlo utilizando una búsqueda JNDI. Siempre que necesite realizar un trabajo transaccional en contra de la base de datos, es irrelevante si está obteniendo una nueva conexión de la fuente de datos o una existente; la mayoría de los grupos de conexiones proporcionarán, de todos modos, la misma conexión que está asociada con el hilo actual (es decir, el que ya utiliza el administrador de entidades). Por lo tanto, evitaría desenvolver al administrador de entidades de esta manera y también realizar actividades transaccionales contra la base de datos; recuerde que el caché de contexto de persistencia y un caché de segundo nivel pueden no sincronizarse si hace esto.
unwrap (java.sql.Connection.class) también no funciona en OpenJPA (al menos 2.1.1) –
@Pawel, que parece estar [ "fijo" en 2.2.0] (https: //issues.apache .org/jira/browse/OPENJPA-1803). –
¡Gracias! sin embargo, no han publicado todavía :) 2.2.0 –
que debe tomar el delegado subyacente utilizando entitymanager.getDelegate()
o entitymanager.unwrap
(que es la mejor manera), echarlo a la implementación específica (en Hibernate
se llama Session
). Luego puede llamar al método connection()
. Tenga en cuenta que esto está en desuso, use la clase Work
en su lugar. Leer más here.
El propio API JPA no parece ofrecer esto, como es lógico, pero si usted está dispuesto para acoplar el código para una aplicación específica, entonces usted puede usar algo como esto (Hibernate):
Session hibernateSession = entityManager.unwrap(Session.class);
Connection jdbcConnection = hibernateSession.connection();
Tenga en cuenta que Session.connection()
está en desuso para su eliminación en Hibernate 4. Considere el uso de Session.doWork()
en su lugar.
En Hibernate, la solución Publicado por skaffman dio lugar a la siguiente mensaje de error:
Hibernate no puede desenvolver org.hsqldb clase.Sesión
Yo conseguir que funcione utilizando SessionImpl en lugar de la sesión:
Connection connection = entityManager().unwrap(SessionImpl.class).connection();
Un ejemplo de solución del problema usando Session.doWork() es la siguiente:
private void executeNative(final String query) {
Session session = entityManager.unwrap(Session.class);
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
Statement s = null;
try {
s = connection.createStatement();
s.executeUpdate(query);
}
finally {
if (s != null) {
s.close();
}
}
}
});
}
debe echarlo a "org.hibernate.Session" y no "org.hsqldb.Session" – dulon
Este funciona de maravilla y puede usar el objeto de conexión en cualquier otro lugar si es necesario
SessionImpl sessionImpl = (SessionImpl) session;
Connection conn = sessionImpl.connection();
Donde session
es el nombre del objeto Sesión de Hibernate
A continuación se muestra el código que funcionó para mí. Utilizamos jpa 1.0, la implementación de Apache openjpa.
import java.sql.Connection;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.OpenJPAPersistence;
public final class MsSqlDaoFactory {
public static final Connection getConnection(final EntityManager entityManager) {
OpenJPAEntityManager openJPAEntityManager = OpenJPAPersistence.cast(entityManager);
Connection connection = (Connection) openJPAEntityManager.getConnection();
return connection;
}
}
En JPA2.0, si es necesario JDBC es por nomodel DTO o entidad de consulta más compleja . A veces APP no es todo ...
espero que esto le ayudará a:
Statement statement = null;
EntityManager em = null;
em = emf.createEntityManager();
EntityTransaction et = em.getTransaction();
if(!et.isActive()) {
et.begin();
}
java.sql.Connection connection = em.unwrap(java.sql.Connection.class);
String qquerry="SELE ...
try {
statement = connection.createStatement();
ResultSet rs = statement.executeQuery(qquerry);
if (!rs.next()) {
return null;
}
else{
wwwwas=rs.getString(4);
}
statement.close();
}
catch (SQLException e) {
System.out.println("\n b-03:"+e);
throw new RuntimeException(e.getMessage(), e);
}
finally {
try {
// em.getTransaction().commit();
if(connection != null)
connection.close();
}
catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
- 1. Java JDBC estado de la conexión
- 2. Cómo obtener el objeto de conexión actual en Spring JDBC
- 3. sin estado y con estado bean de sesión
- 4. Buenas prácticas: JDBC de conexión
- 5. Conexión JDBC segura
- 6. El uso de beans EJB sin estado en un bean de entidad
- 7. Llamar a un método de productor con ámbito de sesión CDI desde un bean de sesión sin estado EJB
- 8. Estado de transacción en JDBC
- 9. Conexión JDBC colgando
- 10. URL de conexión JDBC para Derby Embedded en un Webapp
- 11. Cómo pasar la conexión JDBC sin utilizar Spring/JPA/Hibernate
- 12. JDBC- postgres, conexión rechazada
- 13. ¿Qué es un objeto sin estado en Java?
- 14. Obtención de un estado de objeto
- 15. Obtención de una conexión JDBC de EclipseLink
- 16. Python - Conexión a JDBC
- 17. EJB 3: Acceder a un bean de sesión con estado desde un cliente de aplicación
- 18. Python 3 - Conexión con JDBC
- 19. Establecer programáticamente un objeto de bean específico - Spring DI
- 20. Conexión JDBC con reconexión automática
- 21. Comportamiento de autocommit de conexión JDBC predeterminado
- 22. Conexión a SQL Server LocalDB utilizando JDBC
- 23. Conexión JDBC usando diferentes archivos
- 24. ¿Cómo inyectar un Bean Session en un Bean Driveled Message?
- 25. ¿Cómo obtener el estado de un hilo?
- 26. ¿Cómo obtengo un nuevo bean de sesión con estado en un subproceso de servlet?
- 27. ¿Cómo puedo obtener el SQL de un estado preparado?
- 28. Obtención de una conexión JDBC por JNDI en la primavera de JDBC
- 29. ¿Cómo obtener el número de columnas de un ResultSet JDBC?
- 30. ¿Cómo puedo obtener un objeto HDC de un objeto CDC?
La API JPA no permite tal cosa, aunque la API de JDO hace. – DataNucleus