session.connection ()은 Hibernate에서 더 이상 사용되지 않습니까?


80

우리 java.sql.Connection는 동면 세션 과 관련된 것을 얻을 수 있어야합니다 . 이 연결은 실행중인 트랜잭션과 연관 될 수 있으므로 다른 연결은 작동하지 않습니다.

session.connection ()이 이제 더 이상 사용되지 않는 경우 어떻게해야합니까?


누구든지 이것에 대해 더 많은 것을 읽고 싶다면 : hibernate.onjira.com/browse/HHH-2603
WW.

9
Hibernate라는이 끔찍한 프레임 워크에서 벗어나야하는 많은 이유 중 하나입니다. 이름에서 알 수 있듯이 영원히 잠을 잘 시간입니다.
chrisapotek

2
@chrisapotek 당신은 Hibernate를 좋아하지 않는다 ... 대안이 있거나 모든 지속성 내용을 손으로 작성합니까?
Emaborsa

1
mybatis는 어떻습니까?
Geoffrey Ritchey

답변:


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

1
와. Hibernate 3.2.7.ga를 사용하고 있지만 내 org.hibernate.Session에는 doWork 메서드가 없습니다. 훌륭합니다!
TraderJoeChicago 2010 년

25
못 생겼어. 사람들은 항상 무언가를위한 원시 연결이 필요합니다. 쉽게 만들 수 있어야합니다.
Peter

9
SessionImpl sessionImpl = (SessionImpl) session; Connection conn = sessionImpl.connection();그런 다음 작은 메서드에 국한된 것이 아니라 해당 코드에서 필요하지 않은 경우 어디에서나 연결 개체를 사용할 수 있습니다.
Simon Mbatia

2
Java8- session.doWork(this::doSomething). 사용 doReturningWork () - 당신은 결과를 반환 할 경우
옵티오

22

경우 session.connect()현재 사용되지 않습니다, 어떻게 그렇게 하죠?

Javadoc에 언급 된대로 Session#doWork(Work)WorkAPI 를 사용해야 합니다.

connection()
     더 이상 사용되지 않습니다. (4.x에서 제거 예정). 교체는 필요에 따라 다릅니다. 직접 JDBC 물건 사용을 위해 doWork(org.hibernate.jdbc.Work); '임시 세션'사용 (미정)을 열기 위해.

Hibernate 4.x 이전에 약간의 시간이 있지만 더 이상 사용되지 않는 API를 사용하는 것은 다음과 같습니다.

대체 텍스트:)

업데이트 : RE 에 따르면 : [hibernate-dev] hibernate-dev 목록의 Connection proxying , deprecation의 초기 의도 Session#connection()는 "나쁜"API로 간주 되었기 때문에 사용을 중지하는 것이 었지만 그 시간에 머물기로되어있었습니다. 마음이 바뀌었나 봐 ...


2
여기 내 Javadoc은 귀하의 Javadoc과 약간 다릅니다. 조금 덜 명확합니다. 연결에 대한 작업을 수행하기 위해 SPI로 대체됩니다. 4.x에서 제거 될 예정입니다. JavaDoc은 모든 것을 말합니다. 이 JavaDoc은 아무 말도하지 않습니다.
TraderJoeChicago 2010 년

@Sergio Indeed. 그러나 내가 할 수 있다면 질문에서 사용중인 Hibernate 버전과 같은 중요한 것들을 언급해야합니다. 귀하의 버전은 꽤 오래 Session#connection()되었으며 (Hibernate Core 3.3 의 javadoc에 대안이 언급되어 있습니다) 일반적으로 독자가 추측 할 수없는 것입니다.
Pascal Thivent

@Pascal Version 3.2.7.ga는 Maven에서 찾을 수있는 최신 버전입니다. GroupId = org.hibernate 및 artifactId = hibernate. Maven이 최신 버전을 제공 할 수 있는지 아니면 jar를 복사하고 maven을 무시해야하는지 궁금합니다.
TraderJoeChicago 2010 년

@Sergio 그것은 당신이 오래된 모 놀리 식 jar ( hibernate)를 사용하고 있기 때문이며 hibernate-core더 최신 버전이 아닙니다 . 그리고 최종 버전 (3.5.x)의 경우 JBoss Nexus 저장소 에서 사용할 수 있습니다 .
Pascal Thivent

1
@Pascal 감사합니다! 한 가지 큰 문제는 연결을 전달해야한다는 것입니다. 따라서 Hibernate가 연결을 제공 할 수 없다면 나쁠 것입니다. 이 연결을 다른 방법으로 가져와야합니다. 연결 방법을 비난한다는 생각을 가진 사람은 누구나 다시 생각해야한다고 생각합니다.
TraderJoeChicago

12

이 시도

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

Actuly getSession은 세션 인터페이스 유형을 반환합니다. 세션의 원래 클래스가 무엇인지 확인하고 원래 클래스로 유형 캐스팅 한 다음 연결을 가져옵니다.

행운을 빕니다!


1
❤️ uuuuu 너무 실망 스럽습니다. 읽기 복제본에 배포하기 위해 읽기 전용 연결을 설정하도록 앱을 설정하려고합니다. 감사.
Sam Berry

1
더 많은 찬성표가없는 이유는 무엇입니까? 이렇게하면 안되는 이유가 있습니까? 나를 위해 완벽하게 작동합니다.

@tilper SessionImpl는 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, 나는 이것이 오래되었다는 것을 알고 있지만 지금은 그것을 다루고 있습니다. 그리고 예, 그렇습니다. 모든 세션 구현은 어떻게 든 SessionImplementor의 것입니다.
Reginaldo Santos

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

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

다음은 아직 아무것도 수행하지 않고 에서 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();
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.