Search code examples
jboss7.xjava-ee-6ejb-3.1

Invoked Stateless EJB never change


I'm writing a course on EJBs on JBOSS AS 7 and I have some troubles. I have a simple local stateless EJB :

@Stateless
public class CitationEJB {

    String citation ="Hello Citation";

    public String getCitation(){
        System.out.println("getting citation from :"+this.toString());
        return this.citation;
    }

    public void setCitation(String citation) {
        System.out.println("changing citation to : "+citation);
        this.citation = citation;
    }

    @PostConstruct
    public void sayHello(){
        System.out.println("Hello, I'm a new EJB");
    }
}

Then I invoke a EJB via JNDI in a JSF ManagedBean :

@ManagedBean
@SessionScoped
public class CitationBean {

    //@EJB trying this time with JNDI
    CitationEJB ejb;

    public String getCitation() throws NamingException{
        ejb = lookupCitationEJB();
        return ejb.getCitation();
    }

    public String getCitation2() throws NamingException{
        ejb.setCitation("hello Toto");
        CitationEJB ejb = lookupCitationEJB();
        return ejb.getCitation();
    }

    private static CitationEJB lookupCitationEJB() throws NamingException {
        Hashtable jndiProperties = new Hashtable();
        jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
        Context context = new InitialContext(jndiProperties);
        String jndiName = "java:global/CitationsDyn/CitationEJB!com.citations.ejb.CitationEJB";
        //jndiName = "java:app/CitationsDyn/CitationEJB";  // Works also
        return (CitationEJB) context.lookup(jndiName);
    }
}

Then I show up the CitationEJB.getCitation() with JSF. Everything works fine except that when I make F5, and so a new request, I always have the same object : when I use CitationEJB.setCitation("Hello toto"), then F5, I do have "Hello Toto" and not a brand new Object.

When I use the @EJB annotation to get the EJB, I have the expected behaviour with a new object for every request.

So what I learned is that the EJB is picked in a pool, but when is it destroyed ? I guess that the JNDI lookup is not bound to a Scope as is a JSF page. But how is it exactly specified ?


Solution

  • The lifecycle of a Stateless Session Bean is managed by the container. A number of instances will be created and placed in an instance pool when the EJB is deployed (for example JBoss 6 creates 10 instances by default). The number can scale up or down based on the demand. The EJBs are generally not destoryed after use, but rather put back in to the pool to be used again and again.

    For your application where you want to keep state, a Stateful Session Bean would be the properly choice (or Single Session Bean if you wanted to share state between the instances). With a Stateful Session Bean, the application can cause the EJB to be destoryed by annotating a method with @Remove.