Session.connection() не рекомендуется в Hibernate?
Нам нужно иметь возможность связать java.sql.Connection
сеанса спящего режима. Никакое другое соединение не будет работать, так как это соединение может быть связано с текущей транзакцией.
Если session.connection() теперь устарел, как я должен это делать?
Ответы
Ответ 1
Теперь вам нужно использовать Work API:
session.doWork(
new Work() {
public void execute(Connection connection) throws SQLException
{
doSomething(connection);
}
}
);
Или, в Java 8:
session.doWork(connection -> doSomething(connection));
Ответ 2
Если session.connect()
теперь устарел, как я должен это делать?
Вы должны использовать Session#doWork(Work)
и Work
API, как указано в Javadoc:
connection()
Устаревшее. (запланировано для удаления в 4.x). Замена зависит от необходимости; для использования прямого материала JDBC используйте doWork(org.hibernate.jdbc.Work)
; для открытия использования "временной сессии" (TBD).
У вас есть время до Hibernate 4.x, но, пользуясь устаревшим API, как-то выглядит так:
:)
Обновление: Согласно RE: [hibernate-dev] Проксирование подключения в списке hibernate-dev кажется, что первоначальное намерение отказа было отказать в использовании Session#connection()
, потому что оно было/считается "плохим" API, но оно должно было оставаться в то время. Думаю, они передумали...
Ответ 3
Там есть еще один вариант, в котором задействовано множество приемов, но по крайней мере он не нуждается в отражении, что даст вам возможность проверить время компиляции:
public Connection getConnection(final EntityManager em) {
HibernateEntityManager hem = (HibernateEntityManager) em;
SessionImplementor sim = (SessionImplementor) hem.getSession();
return sim.connection();
}
Вы могли бы сделать это даже "красивее" с помощью нескольких проверок instanceof
, но версия выше работает для меня.
Ответ 4
Попробуйте это
((SessionImpl)getSession()).connection()
Actuly getSession возвращает тип интерфейса сеанса, вы должны увидеть, что является исходным классом для сеанса, введите cast в исходный класс, затем получите соединение.
УДАЧА!
Ответ 5
Вот способ сделать это в Hibernate 4.3, и он не устарел:
Session session = entityManager.unwrap(Session.class);
SessionImplementor sessionImplementor = (SessionImplementor) session;
Connection conn = sessionImplementor.getJdbcConnectionAccess().obtainConnection();
Ответ 6
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);
}
}
Ответ 7
Я нашел эту статью
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
Это то, что я использую и работаю для меня.
Перетащите метод Session в SessionImpl и легко получите объект подключения:
SessionImpl sessionImpl = (SessionImpl) session;
Connection conn = sessionImpl.connection();
где session
- имя вашего сеансового объекта Hibernate.
Ответ 9
С Hibernate
>= 5.0 вы можете получить Connection
следующим образом:
Connection c = sessionFactory.
getSessionFactoryOptions().getServiceRegistry().
getService(ConnectionProvider.class).getConnection();
Ответ 10
Для 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;
}
Ответ 11
Попробуйте следующее:
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;
}
Ответ 12
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();
}
}