【问题标题】:Initial Context Lookup returns same instance | Inject stateless EJB in Pojo初始上下文查找返回相同的实例 |在 Pojo 中注入无状态 EJB
【发布时间】:2012-07-06 20:09:39
【问题描述】:

我正在尝试通过使用上下文查找在 POJO 中注入 EJB。 我期待的是当你做一个

@EJB annotation 

EJB 有一个 entityManager,我从 EJB 的构造函数中的 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 已打开,因为我期待类似无状态 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)

【问题讨论】:

    标签: ejb stateless initial-context


    【解决方案1】:

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

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

    ic.lookup("ReprovProcess/local")
    

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

    总结一下:

    • 当实施不正确确实使客户端可见状态时,不应期望无状态行为。
    • 无法保证从池中返回哪个实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-04
      • 1970-01-01
      • 1970-01-01
      • 2016-12-18
      • 2023-03-31
      • 2012-08-26
      • 1970-01-01
      相关资源
      最近更新 更多