5

そのため、いくつかのレガシー JDBC 呼び出しを含むアプリケーションがあり、追加の JPA アクションで更新する必要があります。同じ DB トランザクションの一部として、JDBC 呼び出しと JPA 呼び出しの両方を実行できる必要があります。問題があれば、OpenJPA 2.1.1 と Postgres 9.1 を使用しています。次のコードは正しく動作しているように見えます。いくつかの基本的なテストを実行したところ、JDBC ステートメントと JPA ステートメントの両方が実行されました。いずれかでエラーが発生すると、ステートメントのペアが実行されません (たとえば、それらは同じ DB トランザクションの一部です)。私が見ていない問題がありますか - 私が違反しているベストプラクティス、またはこの方法で接続オブジェクトを再利用できないその他の理由はありますか?

EntityManager em = _em; //acquired from OpenJPA
em.getTransaction().begin();
Connection conn;
try {
  OpenJPAEntityManager oem = (OpenJPAEntityManager) em.getDelegate();
  conn = oem.getConnection();
  PreparedStatement ps = conn.prepareStatement(myStatement);
  //initialize parameters in ps
  ps.executeUpdate();
  em.merge(myJpaObject);
  em.getTransaction().commit();
} finally {
    if (ps != null && !ps.isClosed()) {
      ps.close();
    }
    if (em.getTransaction().isActive()) {
    em.getTransaction().rollback();
  }
}

ありがとう!

4

1 に答える 1

3

1 つの微調整で、それで問題ないと思います。

OpenJPA のドキュメントがそれについて述べていることは注目に値します。

返された接続は、EntityManager がマネージド トランザクションまたは非オプティミスティック トランザクションにある場合、EntityManager が現在のトランザクションでフラッシュされた場合、または OpenJPAEntityManager.beginStore メソッドを使用して確実にデータストア トランザクションが進行中です。他の EntityManager 操作を試みる前に、返された接続を必ず閉じてください。OpenJPA は、データストア トランザクションが進行中の場合、基礎となるネイティブ接続が解放されないようにします。

あなたの取引は管理されていませんが、楽観的ではないと思います。また、トランザクションの開始と JDBC の実行の間に JPA の作業を行っていないため、おそらく「現在のトランザクションで EntityManager がフラッシュされた場合」に該当すると思います。

あなたがしていないことの1つは、JPAを続行する前に接続を閉じることです。OpenJPA は使用している実際の接続を返さないと思いますが、OpenJPA が作業を再開する前に閉じる必要のあるラッパーがそれを取り囲んでいます。

于 2012-11-21T20:18:38.213 に答える