session.connection()はHibernateで非推奨になりましたか?


80

java.sql.ConnectionHibernateセッションの関連付けを取得できる必要があります。この接続は実行中のトランザクションに関連付けられている可能性があるため、他の接続は機能しません。

session.connection()が非推奨になった場合、どうすればよいですか?


:ケースでは、誰もこのことについてもっと読みたいhibernate.onjira.com/browse/HHH-2603
WW。

9
Hibernateと呼ばれるこのひどいフレームワークから離れる多くの理由の1つ。名前が示すように、それは永遠に眠る時です。
chrisapotek 2012年

2
@chrisapotek Hibernateが好きではありません...他に選択肢はありますか、それともすべての永続性を手作業で作成しますか?
エマボルサ2014

1
mybatisはどうですか?
GeoffreyRitchey20年

回答:


86

ここで、WorkAPIを使用する必要があります。

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

または、Java 8以降では:

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

1
非推奨のものを使用するのは好きではありませんが、これが使用を開始する良い理由だと思います。しかし、私はWorkAPIについて知りませんでした。どうもありがとう。
TraderJoeChicago 2010

1
ワオ。Hibernate 3.2.7.gaを使用していますが、org.hibernate.SessionにdoWorkメソッドがありません。それは素晴らしいことです!
TraderJoeChicago 2010

25
醜いうん。人々は常に何かのために生の接続を必要とします-彼らはそれを簡単にするべきです。
ピーター

9
SessionImpl sessionImpl = (SessionImpl) session; Connection conn = sessionImpl.connection();その後、接続オブジェクトは、小さなメソッドに限定されるだけでなく、そのコード内で必要な他の場所で使用できます。
Simon Mbatia 2015年

2
Java8ではさらに短くなります- session.doWork(this::doSomething)。結果を返したい場合-doReturningWork()を使用
Optio

22

session.connect()が非推奨になった場合、どうすればよいですか?

Javadocに記載されているように、APIを使用する必要がSession#doWork(Work)ありWorkます。

connection()
     非推奨。(4.xでの削除が予定されています)。交換は必要に応じて異なります。直接JDBCのものを使用するためdoWork(org.hibernate.jdbc.Work); 「一時セッション」の使用(未定)を開くため。

Hibernate 4.xの前にしばらく時間がありますが、非推奨のAPIを使用するとどういうわけか次のようになります。

代替テキスト:)

更新:REによると:[hibernate-dev] hibernate-devリストの接続プロキシ、非推奨の当初の意図は、Session#connection()「悪い」APIであると見なされたため、の使用を思いとどまらせることだったようですが、その時にとどまることになっていた。彼らは気が変わったと思います...


2
ここにある私のJavadocは、あなたのJavadocとは少し異なります。少しわかりにくい:接続に対して作業を実行するためにSPIに置き換える。4.xで削除される予定です。あなたのJavaDocはそれをすべて言います。このJavaDocは何も言いません。
TraderJoeChicago 2010

@Sergio確かに。ただし、可能であれば、質問で使用しているHibernateバージョンなどの重要なことについて言及する必要があります。お使いのバージョンはかなり古く(Session#connection()Hibernate Core 3.3のjavadocに代替案が記載されています)、これは通常、読者が推測できないものです。
Pascal Thivent 2010

@Pascalバージョン3.2.7.gaは、Mavenで見つけた最新のものです。GroupId = org.hibernateおよびartifactId = hibernate。Mavenが最新バージョンを提供できるのか、それともjarをコピーしてMavenを無視する必要があるのか​​疑問に思います。
TraderJoeChicago 2010

@Sergioこれは、古いモノリシックjar(hibernate)を使用してhibernate-coreいて、最新バージョンがないためです。また、Ultimateバージョン(3.5.x)の場合、JBossNexusリポジトリで利用できます
Pascal Thivent 2010

1
@Pascalありがとう!大きな問題の1つは、接続を渡す必要があることです。そのため、Hibernateが接続を提供できない場合は、接続が悪くなります。この接続を別の方法で取得する必要があります。接続方法を廃止するというこの考えを持っていた人は誰でも、もう一度考えるべきだと思います。
TraderJoeChicago 2010

12

これを試して

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

実際、getSessionはセッションインターフェイスタイプを返します。セッションの元のクラスが何であるかを確認し、元のクラスに型キャストしてから接続を取得する必要があります。

幸運を!


1
❤️uuuuuなので、これはイライラする必要があります-読み取りレプリカ間で分散するために、読み取り専用接続を設定するようにアプリをセットアップしようとしています。ありがとう。
サム・ベリー

1
なぜこれはより多くの賛成票を持っていないのですか?これを行うべきではない理由はありますか?私にとっては完璧に機能します。

@tilperSessionImplはHibernateの内部パッケージに含まれているため(使用することを意図していません)、実際の実装に依存しています。また、キャストするときに、テストでセッションを簡単にモックすることはできません。
ヴィック

9

まだ多くのキャストが関係している別のオプションがありますが、少なくともリフレクションは必要ありません。これにより、コンパイル時のチェックが返されます。

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

もちろん、いくつinstanceofかのチェックでそれを「よりきれい」にすることもできますが、上記のバージョンは私にとってはうまくいきます。


9

これをHibernate4.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();

ここで、sessionはHibernateセッションオブジェクトの名前です。


8

connection()インターフェイスで非推奨になりました。で引き続き利用できますSessionImpl。Springが行うことを実行して、それを呼び出すことができます。

これがHibernateJpaDialectSpring3.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 2012年

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、によって使用されたものを返すJava8メソッド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.