java 在 Hibernate 中使用 SessionFactory.getCurrentSession() 时获取 Connection 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41183379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 05:44:23  来源:igfitidea点击:

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

javahibernatehibernate-4.xhibernate-5.x

提问by Vicky Thakor

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

我试图ConnectionSessionFactory.getCurrentSession()使用时在 Hibernate 中获取对象。

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 Proxyobject of Sessionso It can't cast it to SessionImplso what are the other ways to get Connectionobject. Or How to SessionImplfrom Proxy object.

getCurrentSession()给出Proxy对象Session所以它不能将它转换为SessionImpl所以有什么其他方法可以获取Connection对象。或如何SessionImpl从代理对象。



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

我尝试了其他选项,但它说getConnectionProvider()找不到方法。

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

注意:我正在使用hibernate-core-5.0.5.Final.jar

回答by Saulius Next

In Hibenate5 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):

Hibenate5 中,我们需要做一些不同的事情(有关更多详细信息,请查看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.

如果你想测试代码,我对 derby db 的配置。

<?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

enter image description here