JPA持続化問題


私のJBOSSアプリケーションサーバーには、このような3つのEJBがあります.
 
@Stateless
@Local({A.class})
@Remote({A.class})
public ABean implements A{

    @EJB
    B b;

    @Override
    public void a(){
        T entity = b.find(@Stateless id);b.delete(entity);
        b.delete(entity);
    }
}
 
 
@Local({B.class})
@Remote({B.class})
public BImpl implements B{

    @PersistenceContext
    protected EntityManager entityManager;

    public T find(Long id){
        return entityManager.find(T.class,id);
    }

    public void delete(T entity){
        system.out.println(entityManager.contains(entity));
        entityManager.remove(entity);
    }

}

 
ここでABean,BImplは無状態セッションBeanであり,それぞれAとBのトラフィックインタフェースがある.またTはエンティティBeanである.CMTを使用し、1つのデータソースしか使用していません.
 
リモートクライアントはJNDIによってAの参照を取得した後、A.a()メソッドを呼び出し、最後に異常を報告した.異常原因は「脱管(detached)エンティティを削除しようとした」ことであり、systemである.out.println(entityManager.contains(entity))出力はfalseであり、すなわち、B.deleteメソッドに伝達されるエンティティが脱管されたEntity Beanであることを証明する.
 
後にABeanを修正する、ABean中のBインタフェースに対して@EJBを利用して容器注入を行うのではなく、JNDIによってローカルインタフェース参照を検索する、この場合、A.a()を実行する方法は可能であり、エラーを報告することなく、system.out.println(entityManager.contains(entity))出力はtrueであり、すなわち、B.deleteメソッドに渡されるエンティティがコンテナによって管理される管理Entity Beanであることを証明する.
 
しかし、ABeanのBインタフェースがJNDIで検索ローカルインタフェースではなくリモートインタフェースである場合、A.a()メソッドを実行するとエラーが報告され、エラーの原因は「脱管(detached)エンティティを削除しようとした」ため、system.out.println(entityManager.contains(entity))出力かfalseか.
 
以上の実験により,JNDIで検索したリモートインタフェースでメソッドが返すEntityBeanは脱管であり,JNDIで検索したローカルインタフェースでメソッドが返すEntityBeanは管理されていると結論した.これは理解できる.しかしなぜ@EJBで容器注入のインターフェースを利用して戻ってきたEntityBeanが脱管したのか.これは本当に説明できません.私もなぜか分かりません.
 
次はネット上で見つけた概念です
 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
永続化コンテキストとトランザクションコンテキストは緩やかに結合されています.厳密には、トランザクション・セッションと共存しています.
 
EntityManager
エンティティ・オブジェクトはEntity Managerによって管理され、EntityManagerと永続化コンテキストによって相互作用します.
エンティティーマネージャには、次の2種類があります.
コンテナクラス:コンテナ型のエンティティマネージャは、コンテナが問題マネージャ間のコラボレーションを担当し、Java EEアプリケーションサーバが提供するのが管理型のエンティティマネージャです.
アプリケーション型:エンティティマネージャのライフサイクルはアプリケーションによって制御され、アプリケーションはjavaxを通過する.persistence.EntityManagerFactotyのcreaeEntityManager EntityManager EntityManagerインスタンスの作成
 
トランザクション範囲のコンテナで管理されるエンティティーマネージャを使用する場合、トランザクションのコミット、トランザクションのロールバック、永続化コンテキストのクリア、エンティティーマネージャのクローズ、およびエンティティのシーケンス化、または分散アプリケーションでのリモートインタフェースでの転送など、エンティティの値別転送によって、管理解除エンティティが生成されます.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
実は依存注入はローカルネーミングサービスでのみ動作し、リモートサーバのオブジェクトを注入することはできません.実際のアプリケーションでは、EJBは他のEJBまたはリソースに使用される場合があります.この場合、JNDIで注釈を検索または注入する必要があります.@EJBを介してインタフェースのルートが注入されている場合は、ローカルであるべきですが、結果はJNDIで取得したローカルインタフェースの実行結果とは異なり、何が起こっているのか分かりません.