【问题标题】:Get Connection object while using SessionFactory.getCurrentSession() in Hibernate在 Hibernate 中使用 SessionFactory.getCurrentSession() 时获取 Connection 对象
【发布时间】:2017-05-02 04:34:01
【问题描述】:

当使用 SessionFactory.getCurrentSession() 时,我试图在 Hibernate 中获取 Connection 对象。

源代码

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

堆栈跟踪

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() 给出SessionProxy 对象,所以它不能将它转换为SessionImpl 那么还有什么其他方法可以得到Connection 对象。或者如何从代理对象SessionImpl


我尝试了其他选项,但它显示getConnectionProvider() 方法未找到。

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

注意:我使用的是hibernate-core-5.0.5.Final.jar

【问题讨论】:

    标签: java hibernate hibernate-4.x hibernate-5.x


    【解决方案1】:

    Hibenate 5 中,我们需要做一些不同的事情(更多详情请查看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());
                }
            });
        }
    }
    

    如果你想测试代码,我对 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>
    

    此应用的输出:

    【讨论】:

    • 还有其他方法吗?我想要它单独因为我在其他类和方法中传递该对象。
    • 我已经更新了代码。请检查您是否可以接受此解决方案。
    • 没有任何方法session.getSession()
    • 您查看过代码吗?这一行 Connection c = ((SessionImpl)sess.getSession()).connection();我想这就是你想要的。
    • 抱歉,我使用的是最新版本的休眠 5.2.3,这解释了为什么我不明白出了什么问题。我建议将现有代码Connection c 变量更改为Connection c = sessionFactory. getSessionFactoryOptions().getServiceRegistry(). getService(ConnectionProvider.class).getConnection();
    猜你喜欢
    • 1970-01-01
    • 2023-04-11
    • 2017-11-26
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    相关资源
    最近更新 更多