私はEclipseLink 2.3.0を使用しています。JPA/EclipseLink:EntityManager.getTransaction()は新しいトランザクションを作成するか、アクティブなトランザクションを返しますか?
EntityManager em = /* get an entity manager */;
em.getTransaction().begin();
// make some changes
em.getTransaction().commit();
変更がデータベースに永続化されていなかった、とのためにこれを見た:私は、私は(それゆえ、コンテナ、無JTAの外で)次のようになり、ユニットテストから呼び出しています方法を持っていますEntityManager.getTransaction()が両方の呼び出しで同じEntityTransactionではなく新しいEntityTransactionを実際に返していることに気付きました。その効果は、最初の呼び出しが新しいトランザクションを作成して開始し、2番目の呼び出しが別のトランザクションを作成し、それをコミットすることです。最初のトランザクションは決してコミットされなかったので、変更は保存されません。
これらのログメッセージが生じたlog.info(em.getTransaction().toString());
log.info(em.getTransaction().toString());
:
INFO: org.ecl[email protected]1e34f445
INFO: org.ecl[email protected]706a4d1a
IDの2つの異なるインスタンスがあることを検証する二つの異なるオブジェクト我々はこのように、これを確認しました。コードをこれに変更する:
EntityManager em = /* get an entity manager */;
EntityTransaction tx = em.getTransaction();
tx.begin();
// make some changes
tx.commit();
...問題を修正しました。今私がコードを実行すると、私は、データベースの作業を行うために生成されたSQL文を見て、データベースを見て、データが変更されています。
トランザクション管理に使用したコードを推奨する多数のコード例がオンラインで(一般的にJPAとEclipseLink向けに)見られているので、この結果に少し驚きました。私はこれについての情報を広範囲に捜したが、何も見つけられなかった。どうしたの?
JPA仕様で、getTransaction()が行うことを正確に指定し、トランザクションが新規であるか同じであるかどうかを特定しました。これを制御するpersistence.xmlには設定がありますか?この振る舞いはJPA仕様の各実装に固有のものですか?
ありがとうございました。
多分私が投稿したコードはうまくいかなかったはずです。私は明確にするために質問に編集しました。 –
私はそれを理解しています。 JPA仕様には、em.getTransaction()を使用してトランザクションを開始してコミットするコードサンプルが含まれているので、私はそれが*うまくいくはずです。したがって、私が言ったように、beginとcommitの間のコードがすでにトランザクションをコミットまたはロールバックしていない限り、EclipseLinkのバグでなければなりません。私の答えはあなたの問題に対する解決策ではなく、コードが機能するはずであるという確認です。私はEclipseLinkにバグを提出することをお勧めします。 –