4

ステートレスEJB3BeanDAOオブジェクトとして機能し、それぞれが異なるデータベーステーブルへのアクセスを提供します)にEntityManagerオブジェクトを注入しています。デプロイメントはJBossAS7で行われます。

次に、EJB3 BeansメソッドでSystem.identityHashCodeを使用してコードを追加し、インジェクトするEntityManagerのさまざまなインスタンスを確認しました(すべてのDAOで同じインスタンスが表示されることを期待しています)。例:

@Stateless
public class AFacade {
    @PersistenceContext(unitName="foo")
    EntityManager em;

    public List<A> findAll() {
         l.info("entity manager is: "+System.identityHashCode(em)+" class is: "+em.getClass().getSimpleName());
         ...
    }

ただし、私が気付いたのは、 PersistenceContextが同じであるにもかかわらず、各DAOAFacadeBFacadeなど)に異なるEntityManager ( identityHashCodeによって報告される)が注入されたことです。実装クラスは、すべての場合でTransactionScopedEntityManagerでした。

これが私に関係するものであるかどうかにかかわらず、この異なるEntityManagerオブジェクトが注入される理由は私にはわかりません。また、EJB3コンテナが実際に実際のEntityManagerにプロキシを挿入する可能性があるため、これらの異なるインスタンスが実際には単一のEntityManagerのプロキシになる可能性があることも理解しています。

4

2 に答える 2

4

注入された EntityManager は、EJB コンテナによって生成されたプロキシです。

トランザクション スコープの Entity Managerの場合、各トランザクションはProvider の Entity Manager の単一の個別のインスタンスを使用します。

このプロキシに対してメソッド呼び出しが行われると、コンテナはjavax.transaction.TransactionSynchronizationRegistry (これは EJB コンテナによって実装されます) をチェックして、このトランザクション用にすでに作成されたプロバイダ EntityManager があるかどうかを確認します。そうでない場合は、プロバイダー Entity Manager を作成し、それを TransactionSynchronizationRegistry に登録してから、メソッド呼び出しを委任します。既に存在する場合は、単にプロバイダー Entity Manager を取得し、メソッド呼び出しをデリゲートします。

Mike Keith と Merrick Schincarol による書籍「Pro JPA2 Mastering the Java Persistence API」によると、トランザクション スコープの EntityManager はステートレスです (第 6 章を参照)。

各 EJB インスタンス オブジェクトに挿入されるプロキシ オブジェクトは異なりますが、トランザクション スコープのエンティティ マネージャのステートレスな性質により、単一のプロキシ オブジェクトを使用することもできます。

こちらもご覧ください: http://piotrnowicki.com/2011/11/am-i-in-the-same-transaction-am-i-using-the-same-persistencecontext/

于 2012-12-09T06:14:15.230 に答える
4

はい、それらは実際のエンティティ マネージャーのプロキシです (実際には、プロキシではなく、スレッド セーフなデコレータだと思います)。

EntityManager が接続のラッパーであることを知っているかどうかはわかりません。このデコレータ (またはプロキシ) がない場合、そのステートレス Bean へのすべての呼び出しが同じ接続 (および場合によってはトランザクション) を共有することになり、これは望ましくありません。

于 2012-11-17T16:44:28.973 に答える