session.connection() deprecated on Hibernate?

JavaHibernateOrm

Java Problem Overview


We need to be able to get the associated java.sql.Connection of a hibernate session. No other connection will work, as this connection may be associated with a running transaction.

If session.connection() is now deprecated, how am I supposed to do that?

Java Solutions


Solution 1 - Java

You now have to use the Work API:

session.doWork(
    new Work() {
        public void execute(Connection connection) throws SQLException 
        { 
            doSomething(connection); 
        }
    }
);

Or, in Java 8+ :

session.doWork(connection -> doSomething(connection)); 

Solution 2 - Java

> If session.connect() is now deprecated, how am I supposed to do that?

You have to use Session#doWork(Work) and the Work API, as mentioned in the Javadoc:

> connection()
>      Deprecated. (scheduled for removal in 4.x). Replacement depends on need; for doing direct JDBC stuff use doWork(org.hibernate.jdbc.Work); for opening a 'temporary Session' use (TBD).

You have some time before Hibernate 4.x but, well, using a deprecated API somehow looks like this:

alt text:)

Update: According to RE: [hibernate-dev] Connection proxying on the hibernate-dev list, it seems that the initial intention of the deprecation was to discourage the use of Session#connection() because it was/is considered as a "bad" API, but it was supposed to stay at that time. I guess they changed their mind...

Solution 3 - Java

Try This

((SessionImpl)getSession()).connection()

Actuly getSession returns Session Interface type, you should see what is the original class for the session, type cast to the original class then get the connection.

GOOD LUCK!

Solution 4 - Java

Here is a way to do it in Hibernate 4.3, and it is not deprecated:

  Session session = entityManager.unwrap(Session.class);
  SessionImplementor sessionImplementor = (SessionImplementor) session;
  Connection conn = sessionImplementor.getJdbcConnectionAccess().obtainConnection();

Solution 5 - Java

This is what I use and works for me. Downcast the Session object into a SessionImpl and get the connection object easily:

SessionImpl sessionImpl = (SessionImpl) session;
Connection conn = sessionImpl.connection();

where session is the name of your Hibernate session object.

Solution 6 - Java

There's another option with still a lot of casts involved, but at least it doesn't need reflection, which will give you back compile time checking:

public Connection getConnection(final EntityManager em) {
  HibernateEntityManager hem = (HibernateEntityManager) em;
  SessionImplementor sim = (SessionImplementor) hem.getSession();
  return sim.connection();
}

You could of course make that even "prettier" with a few instanceof checks, but the version above works for me.

Solution 7 - Java

connection() was just deprecated on the interface. It is still available on SessionImpl. You can do what Spring does and just call that one.

Here is the code from HibernateJpaDialect in Spring 3.1.1

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

Solution 8 - Java

I found this article

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

It helped me.

Solution 9 - Java

With Hibernate >= 5.0 you can get the Connection like this:

Connection c = sessionFactory.
getSessionFactoryOptions().getServiceRegistry().
getService(ConnectionProvider.class).getConnection();

Solution 10 - Java

For hibenate 4.3 try this:

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

Solution 11 - Java

Try this:

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

Solution 12 - Java

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

Solution 13 - Java

Here is a Java 8 method to return the Connection used by an EntityManager without actually doing anything with it yet:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTraderJoeChicagoView Question on Stackoverflow
Solution 1 - JavaKeatsPeeksView Answer on Stackoverflow
Solution 2 - JavaPascal ThiventView Answer on Stackoverflow
Solution 3 - JavaMohammad HosseiniView Answer on Stackoverflow
Solution 4 - JavaLouis-FélixView Answer on Stackoverflow
Solution 5 - JavaSimon MbatiaView Answer on Stackoverflow
Solution 6 - JavaStefan HaberlView Answer on Stackoverflow
Solution 7 - JavaPatrickView Answer on Stackoverflow
Solution 8 - JavaPETRoView Answer on Stackoverflow
Solution 9 - JavayglodtView Answer on Stackoverflow
Solution 10 - JavashcherbakView Answer on Stackoverflow
Solution 11 - JavasegauravView Answer on Stackoverflow
Solution 12 - Javauser2209871View Answer on Stackoverflow
Solution 13 - JavaSteve ChambersView Answer on Stackoverflow