user804979
user804979

Reputation: 933

Initial Context Lookup returns same instance | Inject stateless EJB in Pojo

I am trying to inject a EJB in POJO by using context lookup. What I am expecting is a stateless behavior of EJB as you get when you do a

@EJB annotation 

The EJB has a entityManager which I get from the EntityManagerFactory in the constructor for 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 {
        }

Next I look up the EJB twice such that

But I am not observing this. The second time I do a lookup and do an em.isOpen(), I get a false.

So the question is: Can context.lookup be used for obtaining a stateless EJB like behavior? If not what can be used?

            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());

Output is

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)

Upvotes: 0

Views: 1273

Answers (1)

Mikko Maunu
Mikko Maunu

Reputation: 42094

You misunderstood stateless. It is not about container providing functionality to set instance of stateless bean back to its initial state. Instead developer should keep care that all instances of stateless session bean are interchangeable. This means that stateless bean should never have state that is visible to client. In your case getEm breaks this contract.

Container does have pool of stateless session bean instances. It is decision taken by container which one of these instances is returned. That's why you cannot make any assumptions about which instance is returned by following lookup:

ic.lookup("ReprovProcess/local")

It can be instance that you just used before, it can as well be instance that was never used by any client. If you need state visible to client, use stateful session beans and store reference to it.

To sum it up:

  • One should not expect stateless behavior when implementation incorrectly does have state visible to client.
  • There is no guarantee over which instance is returned from the pool.

Upvotes: 3

Related Questions