Necesitamos poder obtener el asociado java.sql.Connection
de una sesión de hibernación. Ninguna otra conexión funcionará, ya que esta conexión puede estar asociada con una transacción en ejecución.
Si session.connection () ahora está en desuso, ¿cómo se supone que debo hacer eso?
Respuestas:
Ahora tienes que usar la API de trabajo:
session.doWork( new Work() { public void execute(Connection connection) throws SQLException { doSomething(connection); } } );
O, en Java 8+:
fuente
SessionImpl sessionImpl = (SessionImpl) session; Connection conn = sessionImpl.connection();
Luego, puede usar el objeto de conexión en cualquier lugar donde lo necesite en ese código, no solo confinado a un método pequeño.session.doWork(this::doSomething)
. Si desea devolver un resultado, use doReturningWork ()Tienes que usar
Session#doWork(Work)
y laWork
API, como se menciona en el Javadoc:Tiene algo de tiempo antes de Hibernate 4.x pero, bueno, usar una API obsoleta de alguna manera se ve así:
:)
Actualización: De acuerdo con RE: [hibernate-dev] Conexión proxy en la lista de hibernate-dev, parece que la intención inicial de la desaprobación era desalentar el uso de
Session#connection()
porque era / se considera una API "mala", pero se suponía que debía quedarse en ese momento. Supongo que cambiaron de opinión ...fuente
Session#connection()
en Hibernate Core 3.3 menciona la alternativa) y eso es típicamente algo que los lectores no pueden adivinar.hibernate
) y no elhibernate-core
que tiene versiones más recientes. Y para las últimas versiones (3.5.x), están disponibles en el repositorio de JBoss Nexus .Prueba esto
Actuly getSession devuelve el tipo de interfaz de sesión, debería ver cuál es la clase original para la sesión, escriba cast a la clase original y luego obtenga la conexión.
¡BUENA SUERTE!
fuente
SessionImpl
está en un paquete interno de Hibernate (por lo que no está destinado a ser utilizado) y también depende de la implementación real. Además, no puede burlarse fácilmente de la sesión en sus pruebas cuando la lanza.Hay otra opción en la que todavía hay muchos cambios involucrados, pero al menos no necesita reflexión, lo que le devolverá la verificación del tiempo de compilación:
public Connection getConnection(final EntityManager em) { HibernateEntityManager hem = (HibernateEntityManager) em; SessionImplementor sim = (SessionImplementor) hem.getSession(); return sim.connection(); }
Por supuesto, podría hacerlo aún más "bonito" con algunas
instanceof
comprobaciones, pero la versión anterior funciona para mí.fuente
Aquí hay una forma de hacerlo en Hibernate 4.3, y no está en desuso:
fuente
session
aSessionImplementor
?Esto es lo que uso y me funciona. Downcast el objeto Session en un SessionImpl y obtenga el objeto de conexión fácilmente:
donde
session
es el nombre de su objeto de sesión de Hibernate.fuente
connection()
estaba en desuso en la interfaz. Todavía está disponible elSessionImpl
. Puedes hacer lo que hace Spring y simplemente llamar a eso.Aquí está el código de
HibernateJpaDialect
Spring 3.1.1public Connection getConnection() { try { if (connectionMethod == null) { // reflective lookup to bridge between Hibernate 3.x and 4.x connectionMethod = this.session.getClass().getMethod("connection"); } return (Connection) ReflectionUtils.invokeMethod(connectionMethod, this.session); } catch (NoSuchMethodException ex) { throw new IllegalStateException("Cannot find connection() method on Hibernate session", ex); } }
fuente
Encontre este articulo
package com.varasofttech.client; import java.sql.Connection; import java.sql.SQLException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.SessionImpl; import org.hibernate.jdbc.ReturningWork; import org.hibernate.jdbc.Work; import com.varasofttech.util.HibernateUtil; public class Application { public static void main(String[] args) { // Different ways to get the Connection object using Session SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); Session session = sessionFactory.openSession(); // Way1 - using doWork method session.doWork(new Work() { @Override public void execute(Connection connection) throws SQLException { // do your work using connection } }); // Way2 - using doReturningWork method Connection connection = session.doReturningWork(new ReturningWork<Connection>() { @Override public Connection execute(Connection conn) throws SQLException { return conn; } }); // Way3 - using Session Impl SessionImpl sessionImpl = (SessionImpl) session; connection = sessionImpl.connection(); // do your work using connection // Way4 - using connection provider SessionFactoryImplementor sessionFactoryImplementation = (SessionFactoryImplementor) session.getSessionFactory(); ConnectionProvider connectionProvider = sessionFactoryImplementation.getConnectionProvider(); try { connection = connectionProvider.getConnection(); // do your work using connection } catch (SQLException e) { e.printStackTrace(); } } }
Me ayudó.
fuente
Con
Hibernate
> = 5.0 puede obtener loConnection
siguiente:fuente
Para hibenate 4.3 intente esto:
public static Connection getConnection() { EntityManager em = <code to create em>; Session ses = (Session) em.getDelegate(); SessionFactoryImpl sessionFactory = (SessionFactoryImpl) ses.getSessionFactory(); try{ connection = sessionFactory.getConnectionProvider().getConnection(); }catch(SQLException e){ ErrorMsgDialog.getInstance().setException(e); } return connection; }
fuente
Prueba esto:
public Connection getJavaSqlConnectionFromHibernateSession() { Session session = this.getSession(); SessionFactoryImplementor sessionFactoryImplementor = null; ConnectionProvider connectionProvider = null; java.sql.Connection connection = null; try { sessionFactoryImplementor = (SessionFactoryImplementor) session.getSessionFactory(); connectionProvider = (ConnectionProvider) sessionFactoryImplementor.getConnectionProvider().getConnection(); connection = connectionProvider.getConnection(); } catch (SQLException e) { e.printStackTrace(); } return connection; }
fuente
Connection conn = null; PreparedStatement preparedStatement = null; try { Session session = (org.hibernate.Session) em.getDelegate(); SessionFactoryImplementor sfi = (SessionFactoryImplementor) session.getSessionFactory(); ConnectionProvider cp = sfi.getConnectionProvider(); conn = cp.getConnection(); preparedStatement = conn.prepareStatement("Select id, name from Custumer"); ResultSet rs = preparedStatement.executeQuery(); while (rs.next()) { System.out.print(rs.getInt(1)); System.out.println(rs.getString(2)); } } catch (Exception e) { e.printStackTrace(); } finally { if (preparedStatement != null) { preparedStatement.close(); } if (conn != null) { conn.close(); } }
fuente
Aquí hay un método de Java 8 para devolver el
Connection
usado por unEntityManager
sin hacer nada con él todavía:private Connection getConnection(EntityManager em) throws SQLException { AtomicReference<Connection> atomicReference = new AtomicReference<Connection>(); final Session session = em.unwrap(Session.class); session.doWork(connection -> atomicReference.set(connection)); return atomicReference.get(); }
fuente