web-dev-qa-db-ja.com

Java EE 6でJPA2 EntityManagerからデータソースまたは接続を取得する方法

私はJava EE 6とEclipseLinkを永続化するためにEclipse 6を使用し、PostgreSQLデータベースを使用しています。

ユーザー登録の場合、PostgreSQLのパスワードを次のように設定します。

_... password = crypt('inputPassword',gen_salt('bf')) ...
_

これにはDigestUtilsを使用できないため、ユーザーを手動でDBに挿入する必要があります。アプリケーションを構成可能に保つために、InitialContextInstance.lookup(dataSource)を使用してDataSourceにクエリを実行するのではなく、次のようにEntityManagerからデータ(または接続)を抽出します。

_DataSource ds = entityManagerInstance.someFunctionThatReturnsADataSourceOrConnection();
_

または、インジェクションから保護するために、準備済みステートメントと組み合わせてcreateNativeQueryまたは同様のものを使用することは可能でしょうか?

12
zuloo

時々それはグーグルで別の実行をするだけです:

entityManager.getTransaction().begin();
Java.sql.Connection connection = entityManager.unwrap(Java.sql.Connection.class);
...
entityManager.getTransaction().commit();

Eclipse Link Documentation で説明されています。

16
zuloo

承認された回答に対する「Archimedes Trajano」のコメントに応えて、承認された回答はEclipselink以外でも機能しますか?答えは、少なくともHibernateには当てはまりません。

Hibernateの承認された回答を試したところ、次のエラーが発生しました。

Caused by: org.springframework.orm.jpa.JpaSystemException: Hibernate cannot unwrap interface Java.sql.Connection; nested exception is javax.persistence.PersistenceException: Hibernate cannot unwrap interface Java.sql.Connection
     at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.Java:418) ~[spring-orm-4.0.5.RELEASE.jar:4.0.5.RELEASE]

以下のスタックオーバーフローの質問からの回答を組み合わせることで、Hibernateで機能するソリューションを思いつくことができました。

ステートレスBeanからJDBC接続オブジェクトを取得

HibernateはJasperRunManagerのConnectionオブジェクトを取得します

これが私の解決策です:

    Session hibernateSession = entityManager.unwrap(Session.class);

    hibernateSession.doWork(new org.hibernate.jdbc.Work() {

        @Override
        public void execute(Connection connection) throws SQLException {
            // do whatever you need to do with the connection
        }
    });
5
dulon

Dulonの回答に基づいて、Hibernate 4で動作するコードのスニペットを次に示します

Connection getConnection() {
        Session session = entityManager.unwrap(Session.class);
        MyWork myWork = new MyWork();
        session.doWork(myWork);
        return myWork.getConnection();
}


private static class MyWork implements Work {

    Connection conn;

    @Override
    public void execute(Connection arg0) throws SQLException {
        this.conn = arg0;
    }

    Connection getConnection() {
        return conn;
    }

}
0
uvperez