session.connection()在Hibernate上已弃用?


80

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

如果现在不建议使用session.connection(),该怎么办?


如果有人想阅读更多有关此的信息,请访问:hibernate.onjira.com/browse/HHH-2603
WW。

9
远离这个可怕的框架Hibernate的众多原因之一。顾名思义,是时候让它永远睡着了。
chrisapotek'5

2
@chrisapotek您不喜欢Hibernate ...您是否有其他选择,还是手动编写了所有持久性资料?
Emaborsa 2014年

1
mybatis怎么样?
Geoffrey Ritchey

Answers:


86

现在,您必须使用Work API:

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

或者,在Java 8+中:

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

1
我不喜欢使用不赞成使用的东西,但是我想这是开始使用它的一个很好的理由。但是我不了解Work API。非常感谢。
TraderJoeChicago 2010年

1
哇。我正在使用Hibernate 3.2.7.ga,但我的org.hibernate.Session没有任何doWork方法。那很棒!
TraderJoeChicago

25
真丑。人们总是需要某种东西的原始连接-他们应该使它变得容易。
彼得

9
SessionImpl sessionImpl = (SessionImpl) session; Connection conn = sessionImpl.connection();然后,您可以在该代码中您需要的任何地方使用连接对象,而不仅限于一个小的方法。
西蒙·姆巴蒂亚

2
在Java8-中甚至更短session.doWork(this::doSomething)。如果要返回结果,请使用doReturningWork()
Optio

22

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

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

connection()
     不推荐使用。(已计划在4.x中删除)。更换取决于需要;用于直接使用JDBC doWork(org.hibernate.jdbc.Work); 用于打开“临时会话”用途(TBD)。

您有一些时间来使用Hibernate 4.x,但是好了,使用不赞成使用的API看起来像这样:

替代文字:)

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


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

@塞尔吉奥确实。但是,如果可以的话,您应该提到一些重要的问题,例如您在问题中使用的Hibernate版本。您的版本很旧(Session#connection()Hibernate Core 3.3中的javadoc提到了替代版本),通常读者无法猜到。
Pascal Thivent

@Pascal版本3.2.7.ga是我在Maven上可以找到的最新版本。GroupId = org.hibernate和artifactId =休眠。我想知道Maven是否可以提供最新版本,还是只需要复制jar并忽略maven。
TraderJoeChicago

@Sergio那是因为您使用的是旧的整体式jar(hibernate),而不是hibernate-core具有较新的版本。对于最终版本(3.5.x),可以在JBoss Nexus存储库中找到它们。
Pascal Thivent

1
@Pascal谢谢!一个大问题是我需要传递连接,因此,如果Hibernate无法为我提供其连接,那就不好了。我将需要以其他方式获得此连接。我认为凡是不赞成使用连接方法的人都应该再考虑一下。
TraderJoeChicago 2010年

12

试试这个

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

Actuly getSession返回会话接口类型,您应该查看会话的原始类是什么,将类型强制转换为原始类,然后获得连接。

祝好运!


1
❤️uuuuu,所以这很令人沮丧-尝试使我的应用设置设置只读连接,以便在多个只读副本之间分发。谢谢。
山姆·贝瑞

1
为什么没有更多的投票?是否有某些原因不应该这样做?非常适合我。

@tilperSessionImpl在Hibernate的内部包中(因此不打算使用),这也取决于实际的实现。同样,当您投射会话时,您也无法在测试中轻松模拟会话。
维克(Vic)

9

还有另一个选项仍然涉及很多强制转换,但是至少不需要反射,这将使您返回编译时检查:

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

您当然可以做一些instanceof检查,甚至使它“更漂亮” ,但是上面的版本对我有用。


9

这是在Hibernate 4.3中实现的一种方法,并且不建议使用:

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

1
转换session为安全SessionImplementor吗?
macemers 2015年

@DerekY,我知道这很旧了,但是现在就解决。是的,是的。所有Session实现也是SessionImplementor的某种方式。
雷吉纳尔多·桑托斯

9

这就是我使用并为我工作的方式。将Session对象转换为SessionImpl并轻松获得连接对象:

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

sessionHibernate会话对象的名称在哪里。


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

15
令人敬畏的Hibernate就是您要做的这种事情。很少有框架像Hibernate这样糟糕。
chrisapotek'5

8

我发现这篇文章

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

它帮助了我。


6

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

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

3

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

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

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

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();
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.