우리 java.sql.Connection
는 동면 세션 과 관련된 것을 얻을 수 있어야합니다 . 이 연결은 실행중인 트랜잭션과 연관 될 수 있으므로 다른 연결은 작동하지 않습니다.
session.connection ()이 이제 더 이상 사용되지 않는 경우 어떻게해야합니까?
우리 java.sql.Connection
는 동면 세션 과 관련된 것을 얻을 수 있어야합니다 . 이 연결은 실행중인 트랜잭션과 연관 될 수 있으므로 다른 연결은 작동하지 않습니다.
session.connection ()이 이제 더 이상 사용되지 않는 경우 어떻게해야합니까?
답변:
이제 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()
현재 사용되지 않습니다, 어떻게 그렇게 하죠?
Javadoc에 언급 된대로 Session#doWork(Work)
및 Work
API 를 사용해야 합니다.
connection()
더 이상 사용되지 않습니다. (4.x에서 제거 예정). 교체는 필요에 따라 다릅니다. 직접 JDBC 물건 사용을 위해doWork(org.hibernate.jdbc.Work)
; '임시 세션'사용 (미정)을 열기 위해.
Hibernate 4.x 이전에 약간의 시간이 있지만 더 이상 사용되지 않는 API를 사용하는 것은 다음과 같습니다.
:)
업데이트 : RE 에 따르면 : [hibernate-dev] hibernate-dev 목록의 Connection proxying , deprecation의 초기 의도 Session#connection()
는 "나쁜"API로 간주 되었기 때문에 사용을 중지하는 것이 었지만 그 시간에 머물기로되어있었습니다. 마음이 바뀌었나 봐 ...
Session#connection()
되었으며 (Hibernate Core 3.3 의 javadoc에 대안이 언급되어 있습니다) 일반적으로 독자가 추측 할 수없는 것입니다.
hibernate
)를 사용하고 있기 때문이며 hibernate-core
더 최신 버전이 아닙니다 . 그리고 최종 버전 (3.5.x)의 경우 JBoss Nexus 저장소 에서 사용할 수 있습니다 .
이 시도
((SessionImpl)getSession()).connection()
Actuly getSession은 세션 인터페이스 유형을 반환합니다. 세션의 원래 클래스가 무엇인지 확인하고 원래 클래스로 유형 캐스팅 한 다음 연결을 가져옵니다.
행운을 빕니다!
SessionImpl
는 Hibernate의 내부 패키지에 있으며 (사용할 의도가 없음) 실제 구현에 대한 종속성입니다. 또한 캐스트 할 때 테스트에서 세션을 쉽게 모의 할 수 없습니다.
여전히 많은 캐스트가 관련된 또 다른 옵션이 있지만 적어도 리플렉션이 필요하지 않으므로 컴파일 시간을 다시 확인할 수 있습니다.
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();
}
}
다음은 아직 아무것도 수행하지 않고 에서 Connection
사용 된 을 반환하는 Java 8 메서드입니다 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();
}