Necesitamos poder obtener el asociado java.sql.Connectionde 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 laWorkAPI, 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-coreque 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
SessionImplestá 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
instanceofcomprobaciones, 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
sessionaSessionImplementor?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
sessiones 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
HibernateJpaDialectSpring 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 loConnectionsiguiente: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
Connectionusado por unEntityManagersin 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