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

Tra*_*ago 76 java orm hibernate

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

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

Kea*_*eks 85

您现在必须使用Work API:

session.doWork(
    new Work() {
        public void execute(Connection connection) throws SQLException 
        { 
            doSomething(connection); 
        }
    }
);
Run Code Online (Sandbox Code Playgroud)

或者,在Java 8中:

session.doWork(connection -> doSomething(connection)); 
Run Code Online (Sandbox Code Playgroud)

  • 哎呀,这很难看.人们总是需要原始连接 - 他们应该让它变得容易. (25认同)
  • `SessionImpl sessionImpl =(SessionImpl)session; Connection conn = sessionImpl.connection();`然后,您可以在该代码中的任何地方使用连接对象,而不仅仅局限于一个小方法. (8认同)
  • 在Java8中更短-```session.doWork(this :: doSomething)```。如果要返回结果,请使用doReturningWork() (2认同)

Pas*_*ent 23

如果session.connect()现在已经弃用了,我该怎么做呢?

您必须使用Session#doWork(Work)WorkJavadoc中提到的API:

connection()
     已过时.(计划在4.x中删除).更换取决于需要; 用于直接使用JDBC的东西doWork(org.hibernate.jdbc.Work); 用于打开"临时会话"使用(TBD).

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

替代文字:)

更新:根据RE:[hibernate-dev]连接代理在hibernate-dev列表中,似乎弃用的初衷是阻止使用,Session#connection()因为它被认为是"坏"API,但它应该留在那个时候.我想他们改变了主意......

  • 我的Javadoc与您的Javadoc略有不同。只是一点点不清楚:将被SPI代替以执行针对该连接的工作;计划在4.x中删除。您的JavaDoc可以说明一切。这个JavaDoc什么也没说。 (2认同)

小智 12

试试这个

((SessionImpl)getSession()).connection()
Run Code Online (Sandbox Code Playgroud)

Actuly getSession返回会话接口类型,您应该看到会话的原始类是什么,键入强制转换为原始类然后获取连接.

祝好运!


Ste*_*erl 9

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

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

你当然可以通过一些instanceof检查使它更"漂亮" ,但上面的版本对我有用.


小智 9

这是在Hibernate 4.3中执行此操作的一种方法,并且不会弃用它:

  Session session = entityManager.unwrap(Session.class);
  SessionImplementor sessionImplementor = (SessionImplementor) session;
  Connection conn = sessionImplementor.getJdbcConnectionAccess().obtainConnection();
Run Code Online (Sandbox Code Playgroud)


Sim*_*tia 9

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

SessionImpl sessionImpl = (SessionImpl) session;
Connection conn = sessionImpl.connection();
Run Code Online (Sandbox Code Playgroud)

session您的Hibernate会话对象的名称在哪里.


Pat*_*ick 8

connection()刚刚在界面上弃用了.它仍然可用SessionImpl.你可以做Spring做的事情,只需要调用那个.

这是HibernateJpaDialectSpring 3.1.1中的代码

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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 这是令人敬畏的Hibernate让你做的事情.很少有框架像Hibernate那么糟糕. (15认同)

小智 6

我找到了这篇文章

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();
    }
}
}
Run Code Online (Sandbox Code Playgroud)

它帮助了我.


ygl*_*odt 6

使用Hibernate> = 5.0,您可以得到Connection如下所示:

Connection c = sessionFactory.
getSessionFactoryOptions().getServiceRegistry().
getService(ConnectionProvider.class).getConnection();
Run Code Online (Sandbox Code Playgroud)