session.connection()在Hibernate上不赞成使用?

时间:2010-08-19 21:49:13

标签: java hibernate orm

我们需要能够获得hibernate会话的关联java.sql.Connection。没有其他连接可以工作,因为此连接可能与正在运行的事务相关联。

如果现在不推荐使用session.connection(),我该怎么办呢?

13 个答案:

答案 0 :(得分:82)

您现在必须使用Work API:

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

或者,在Java 8+中:

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

答案 1 :(得分:23)

  

如果session.connect()现已弃用,我该怎么办呢?

您必须使用Session#doWork(Work)Work API,如Javadoc中所述:

  

connection()
  已弃用。(计划在4.x中删除)。更换取决于需要;用于直接JDBC的东西使用doWork(org.hibernate.jdbc.Work);开启“临时会议”使用(TBD)。

你有一些时间在Hibernate 4.x之前,但是,使用不推荐的API看起来像这样:

alt text:)

更新:根据hibernate-dev列表中的 RE: [hibernate-dev] Connection proxying ,似乎弃用的初衷是阻止使用{{ 1}}因为它被认为是一个“坏”的API,但它应该留在那个时候。我想他们改变了主意......

答案 2 :(得分:10)

试试这个

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

Actuly getSession返回会话接口类型,您应该看到会话的原始类是什么,输入到原始类然后获取连接。

好运!

答案 3 :(得分:9)

还有另一个选项,但仍然涉及很多演员,但至少它不需要反射,这会让你回复编译时间:

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

当然,您可以通过一些instanceof检查使其更“漂亮”,但上面的版本对我有效。

答案 4 :(得分:9)

以下是在Hibernate 4.3中执行此操作的方法,并且不推荐使用它:

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

答案 5 :(得分:9)

这是我使用和为我工作的。 将Session方法向下转换为SessionImpl并轻松获取连接对象:

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

其中session是Hibernate会话对象的名称。

答案 6 :(得分:8)

connection()刚刚在界面上弃用。它仍然可以在SessionImpl上找到。你可以做Spring所做的事情,只需称之为。

以下是Spring 3.1.1中HibernateJpaDialect的代码

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

答案 7 :(得分:6)

我找到了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();
    }
}
}

它帮助了我。

答案 8 :(得分:5)

使用Hibernate&gt; = 5.0,您可以获得Connection,如下所示:

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

答案 9 :(得分:3)

对于hibernate 4.3试试这个:

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

答案 10 :(得分:1)

试试这个:

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

答案 11 :(得分:0)

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

答案 12 :(得分:0)

这是一种Java 8方法,用于返回Connection使用的EntityManager,而实际上并未对其进行任何操作:

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