javajakarta-eeejbejb-3.1stateful-session-bean

Stateless and Stateful Enterprise Java Beans


I am going through the Java EE 6 tutorial and I am trying to understand the difference between stateless and stateful session beans. If stateless session beans do not retain their state in between method calls, why is my program acting the way it is?

package mybeans;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;

@LocalBean
@Stateless
public class MyBean {

    private int number = 0;

    public int getNumber() {
        return number;
    }

    public void increment() {
        this.number++;
    }
}

The client

import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;
import mybeans.MyBean;
import java.io.PrintWriter;

@WebServlet(name = "ServletClient", urlPatterns = { "/ServletClient" })
public class ServletClient extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @EJB
    MyBean mybean;

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        PrintWriter out = response.getWriter();
        mybean.increment();
        out.println(mybean.getNumber());
    }

}

I was expecting getNumber to return 0 every time but it is returning 1 and reloads of the servlet in my browser increase it more. The problem is with my understanding of how stateless session beans work and not with the libraries or application server, of course. Can somebody give me a simple hello world type example of a stateless session bean that behaves differently when you change it to stateful?


Solution

  • The important difference is not private member variables, but associating state with a particular user (think "shopping cart").

    The stateful piece of stateful session bean is like the session in servlets. Stateful session beans allow your app to still have that session even if there isn't a web client. When the app server fetches a stateless session bean out of the object pool, it knows that it can be used to satisfy ANY request, because it's not associated with a particular user.

    A stateful session bean has to be doled out to the user that got it in the first place, because their shopping cart info should be known only to them. The app server ensures that this is so. Imagine how popular your app would be if you could start shopping and then the app server gave your stateful session bean to me when I came along!

    So your private data member is indeed "state", but it's not "shopping cart". Try to redo your (very good) example to make it so the incremented variable is associated with a particular user. Increment it, create a new user, and see if they can still see the incremented value. If done correctly, every user should see just their version of the counter.