4

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

1 Answer 1

19

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

Sign up to request clarification or add additional context in comments.

7 Comments

Is there any other way? I want it separately coz I'm passing that object in other class and methods.
I have updated code. Please check maybe this solution will be acceptable for you.
There ain't any method session.getSession()
Have you look to the code? This line Connection c = ((SessionImpl)sess.getSession()).connection(); I think that's what you want.
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();
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.