0

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

@EJB annotation 

EJB 有一个 entityManager,我从构造函数中的 EntityManagerFactory 获得,用于 thr EJB

        @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 已打开,因为我期待类似无状态 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)
4

1 回答 1

3

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

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

ic.lookup("ReprovProcess/local")

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

把它们加起来:

  • 当实现不正确确实具有对客户端可见的状态时,不应期望无状态行为。
  • 无法保证从池中返回哪个实例。
于 2012-07-09T04:45:56.733 回答