初始上下文查找返回相同的实例|在Pojo中注入无状态EJB

时间:2012-07-06 20:09:39

标签: ejb stateless initial-context

我试图通过使用上下文查找在POJO中注入EJB。 我期待的是当你执行

时获得的EJB的无状态行为
@EJB annotation 

EJB有一个entityManager,我从thrity构造函数中的EntityManagerFactory获取

        @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,

    第一次检索时
  • 我关闭了entitymanager

  • 然后在第二次查找时我应该看到EntityManager是打开的,因为我期待像Stateless EJB这样的行为。

但我没有观察到这一点。我第二次查找并执行em.isOpen()时,我得到了一个错误。

所以问题是:context.lookup是否可以用于获取类似行为的无状态EJB? 如果不是可以使用什么?

            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)

1 个答案:

答案 0 :(得分:2)

你误解了无国籍。它不是关于容器提供将无状态bean的实例设置回其初始状态的功能。相反,开发人员应该注意无状态会话bean的所有实例都是可以互换的。这意味着无状态bean永远不应该具有客户端可见的状态。在您的情况下,getEm违反了此合同。

Container确实有无状态会话bean实例池。容器决定返回其中一个实例。这就是为什么你不能通过以下查找做出关于返回哪个实例的任何假设:

ic.lookup("ReprovProcess/local")

它可以是您之前使用的实例,也可以是任何客户端从未使用过的实例。如果您需要对客户端可见的状态,请使用有状态会话Bean并存储对它的引用。

总结一下:

  • 如果实施不正确,客户端可以看到状态,则不应期望无状态行为。
  • 无法保证从池中返回哪个实例。