我们需要能够获得java.sql.Connection
休眠会话的关联。没有其他连接可用,因为此连接可能与正在运行的事务关联。
如果现在不建议使用session.connection(),该怎么办?
我们需要能够获得java.sql.Connection
休眠会话的关联。没有其他连接可用,因为此连接可能与正在运行的事务关联。
如果现在不建议使用session.connection(),该怎么办?
Answers:
现在,您必须使用Work API:
session.doWork(
new Work() {
public void execute(Connection connection) throws SQLException
{
doSomething(connection);
}
}
);
或者,在Java 8+中:
session.doWork(connection -> doSomething(connection));
SessionImpl sessionImpl = (SessionImpl) session; Connection conn = sessionImpl.connection();
然后,您可以在该代码中您需要的任何地方使用连接对象,而不仅限于一个小的方法。
session.doWork(this::doSomething)
。如果要返回结果,请使用doReturningWork()
如果
session.connect()
现在已弃用,我应该怎么做?
您必须使用Session#doWork(Work)
和Work
API,如Javadoc中所述:
connection()
不推荐使用。(已计划在4.x中删除)。更换取决于需要;用于直接使用JDBCdoWork(org.hibernate.jdbc.Work)
; 用于打开“临时会话”用途(TBD)。
您有一些时间来使用Hibernate 4.x,但是好了,使用不赞成使用的API看起来像这样:
:)
更新:根据RE:[hibernate-dev] hibernate-dev列表上的连接代理,似乎弃用的最初意图是阻止使用Session#connection()
它,因为它被认为是“不良” API,但是它应该留在那个时候。我想他们改变了主意...
Session#connection()
Hibernate Core 3.3中的javadoc提到了替代版本),通常读者无法猜到。
还有另一个选项仍然涉及很多强制转换,但是至少不需要反射,这将使您返回编译时检查:
public Connection getConnection(final EntityManager em) {
HibernateEntityManager hem = (HibernateEntityManager) em;
SessionImplementor sim = (SessionImplementor) hem.getSession();
return sim.connection();
}
您当然可以做一些instanceof
检查,甚至使它“更漂亮” ,但是上面的版本对我有用。
这是在Hibernate 4.3中实现的一种方法,并且不建议使用:
Session session = entityManager.unwrap(Session.class);
SessionImplementor sessionImplementor = (SessionImplementor) session;
Connection conn = sessionImplementor.getJdbcConnectionAccess().obtainConnection();
session
为安全SessionImplementor
吗?
connection()
在界面上已被弃用。在上仍然可用SessionImpl
。您可以执行Spring所要做的,而只需调用它即可。
这是HibernateJpaDialect
Spring 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);
}
}
我发现这篇文章
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();
}
}
}
它帮助了我。
对于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;
}
试试这个:
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;
}
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();
}
}
这是一种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();
}