在 Hibernate 上不推荐使用 session. connect() ?

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

如果 session. connect ()现在已被弃用,那么我应该如何做到这一点?

90339 次浏览

您现在必须使用 WorkAPI:

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

或者,在 Java < 8:

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

如果 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 列表中的 Http://www.mail-archive. com/hibernate-dev@lists.jboss.org/msg00133.html rel = “ nofollow norefrer”> RE: [ hibernate-dev ]连接代理,似乎弃用的最初意图是阻止使用 Session#connection(),因为它被认为是一个“坏”API,但它应该在那个时候停留。我猜他们改变主意了。

connection()刚刚在接口上被废弃了。它仍然在 SessionImpl上可用。你可以像 Spring 那样调用它。

下面是 Spring3.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);
}
}

还有一个选项仍然涉及大量的强制转换,但至少它不需要反射,这将返回编译时间检查:

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

当然,你可以通过一些 instanceof检查使它更加“漂亮”,但是上面的版本对我来说是可行的。

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

试试这个

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

实际上,getSession 返回 Session Interface 类型,您应该看到会话的原始类,输入强制转换到原始类,然后获得连接。

祝你好运!

试试这个:

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

对于 Hibenate 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;
}

在 Hibernate 4.3中有一种方法可以做到这一点,而且不会被弃用:

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

这就是我使用和为我工作的东西。 将 Session 对象下转为 SessionImpl 并轻松获得连接对象:

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

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

我找到 这篇文章

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

它帮助了我。

使用 Hibernate > = 5.0,你可以得到这样的 Connection:

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

下面是一个 Java8方法,它可以返回 EntityManager使用的 Connection,而不需要对它进行任何实际操作:

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