Get Connection object while using SessionFactory.getCurrentSession() in Hibernate

22,949

In Hibenate 5 we need to do things a little bit different (for more details check https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html):

import java.sql.Connection;
import java.sql.SQLException;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.Metadata;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.jdbc.Work;


public class Htest {

    public static void main(String ... args) throws SQLException {
        StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
                .configure("hibernate.cfg.xml")
                .build();

        Metadata metadata = new MetadataSources( standardRegistry )
                .addAnnotatedClass(TesEntity.class)
                .buildMetadata();

        SessionFactory sessionFactory = metadata.getSessionFactoryBuilder()
                .build();

        //one way to get connection version 5.0.2
        Connection c = sessionFactory.
                getSessionFactoryOptions().getServiceRegistry().
                getService(ConnectionProvider.class).getConnection();

        Session sess = null;
        try {
            sess = sessionFactory.getCurrentSession();
        } catch (org.hibernate.HibernateException he) {
            sess = sessionFactory.openSession();
        }


        //If you are using latest version 5.2.3 you can use this line below
        //Connection c =  ((SessionImpl)sess.getSession()).connection();
        System.out.println(c.getMetaData().getDatabaseProductName());

        //another way to get connection
        sess.doWork(new Work() {
            @Override
            public void execute(Connection connection) throws SQLException {
                //connection accessible here
                System.out.println(connection.getMetaData().getDatabaseProductName());
            }
        });
    }
}

My configuration to derby db if you wan to test code.

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.ClientDriver</property>
        <property name="hibernate.connection.url">jdbc:derby://localhost:1527/mytest;create=fasle</property>
        <!-- <property name="connection.username"/> -->
        <!-- <property name="connection.password"/> -->

        <!-- DB schema will be updated if needed -->
        <!-- <property name="hbm2ddl.auto">update</property> -->
    </session-factory>
</hibernate-configuration>

Output of this app :

enter image description here

Share:
22,949
Vicky Thakor
Author by

Vicky Thakor

www.javaquery.com

Updated on December 21, 2020

Comments

  • Vicky Thakor
    Vicky Thakor over 3 years

    I'm trying to get Connection object in Hibernate when SessionFactory.getCurrentSession() is used.

    Source code

    import java.sql.Connection;
    import java.sql.DatabaseMetaData;
    import java.sql.SQLException;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.internal.SessionImpl;
    
    public class SOExample {
        public static void main(String[] args) throws SQLException {
            Configuration configuration = new Configuration();
            SessionFactory  sessionFactory = configuration.buildSessionFactory(new StandardServiceRegistryBuilder().configure().build());
            Session session = sessionFactory.getCurrentSession();
            Connection connection = ((SessionImpl) session).connection();
            // doing operation on connection object as per my requirement
            DatabaseMetaData databaseMetaData = connection.getMetaData();
            System.out.println(databaseMetaData.getDatabaseProductName());
        }
    }
    

    Stacktrace

    Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy24 cannot be cast to org.hibernate.internal.SessionImpl
        at com.SOExample.main(SOExample.java:20)
    

    getCurrentSession() gives Proxy object of Session so It can't cast it to SessionImpl so what are the other ways to get Connection object. Or How to SessionImpl from Proxy object.


    Other option I tried but it says getConnectionProvider() method not found.

    SessionFactoryImplementor sessionFactoryImplementation = (SessionFactoryImplementor) session.getSessionFactory();
    ConnectionProvider connectionProvider = sessionFactoryImplementation.getConnectionProvider();
    try {
        Connection connection = connectionProvider.getConnection();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    

    Note: I'm using hibernate-core-5.0.5.Final.jar

  • Vicky Thakor
    Vicky Thakor over 7 years
    Is there any other way? I want it separately coz I'm passing that object in other class and methods.
  • Saulius Next
    Saulius Next over 7 years
    I have updated code. Please check maybe this solution will be acceptable for you.
  • Vicky Thakor
    Vicky Thakor over 7 years
    There ain't any method session.getSession()
  • Saulius Next
    Saulius Next over 7 years
    Have you look to the code? This line Connection c = ((SessionImpl)sess.getSession()).connection(); I think that's what you want.
  • Vicky Thakor
    Vicky Thakor over 7 years
    Thats what I'm talking about there ain't method getSession() for sess.getSession()
  • Saulius Next
    Saulius Next over 7 years
    Apologies I was using latest version of hibernate 5.2.3, this explains why i couldn't understood what was wrong. I suggest to change in existing code Connection c variable to Connection c = sessionFactory. getSessionFactoryOptions().getServiceRegistry(). getService(ConnectionProvider.class).getConnection();
  • Vicky Thakor
    Vicky Thakor over 7 years
    This is working fine. Can you please update your code with Connection c = sessionFactory. getSessionFactoryOptions().getServiceRegistry(). getService(ConnectionProvider.class).getConnection(); so I can accept it. Thanks