0

コンテキスト ルックアップを使用して POJO に EJB を挿入しようとしています。私が期待しているのは、EJB のステートレスな動作です。

@EJB annotation 

EJB には、EJB のコンストラクターの EntityManagerFactory から取得した entityManager があります。

        @Stateless
        Class ReprovProcess implements ReprovisioningProcess {
        protected EntityManager em;
        public ReprovProcess(){
        //init em from entityManagerFactory;
        }

        public EntityManager getEm(){
        return em;
        }
        }

        @LocalBinding(jndiBinding = "ReprovProcess/local")
        class interface ReprovisioningProcess {
        }

次に、EJB を 2 回検索します。

  • 最初の取得時に、entitymanager を閉じます

  • 次に、2 回目のルックアップで、Stateless EJB のような動作を期待しているため、EntityManager が開いていることがわかります。

しかし、私はこれを観察していません。2 回目にルックアップを実行して を実行するとem.isOpen()、false が返されます。

問題は、状態のない EJB のような動作を取得するために context.lookup を使用できるかということです。そうでない場合、何が使用できますか?

            ReprovisioningProcess pro = (ReprovisioningProcess)                         
            ic.lookup("ReprovProcess/local");
            EntityManager em = pro.getEm();
            System.out.println("Entity Manager State = "+em.isOpen());
            em.close();
            System.out.println("Entity Manager State = "+em.isOpen());

            pro = (NetElementReprovisioningProcess) ic.lookup("ReprovProcess/local");
            em = pro.getEm();
            System.out.println("Entity Manager State = "+em.isOpen());
            em.close();
            System.out.println("Entity Manager State = "+em.isOpen());

出力は

Entity Manager State = true
Entity Manager State = false
Entity Manager State = false
------------- ---------------- ---------------

EntityManager is closed
java.lang.IllegalStateException: EntityManager is closed
at org.hibernate.ejb.EntityManagerImpl.close(EntityManagerImpl.java:97)
at com.cisco.cgms.factoryconfig.reprovision.ReprovisiongGroupTest.testIntialLookup(ReprovisiongGroupTest.java:135)
4

1 に答える 1

3

あなたはstatelessを誤解しています。ステートレス Bean のインスタンスを初期状態に戻す機能を提供するコンテナーに関するものではありません。代わりに、開発者は、ステートレス セッション Bean のすべてのインスタンスが交換可能であることに注意する必要があります。これは、ステートレス Bean がクライアントに見える状態を持つべきではないことを意味します。あなたの場合getEm、この契約を破ります。

コンテナーには、ステートレス セッション Bean インスタンスのプールがあります。これらのインスタンスのどれが返されるかは、コンテナーによって決定されます。そのため、次のルックアップでどのインスタンスが返されるかを推測することはできません。

ic.lookup("ReprovProcess/local")

直前に使用したインスタンスである場合もあれば、クライアントによって使用されたことのないインスタンスである場合もあります。クライアントに状態を表示する必要がある場合は、ステートフル セッション Bean を使用し、それへの参照を保存します。

要約すると:

  • 実装がクライアントに見える状態を誤って持っている場合、ステートレスな動作を期待するべきではありません。
  • プールからどのインスタンスが返されるかについての保証はありません。
于 2012-07-09T04:45:56.733 に答える