Lookup returns new instance of Stateful session be

2020-06-21 06:16发布

问题:

I am using Java EE 5, EJB 3.0, Jboss AS 4.3.2.
I have simplest Stateful bean

@Local
public interface IStateBean 
{
}
@Stateful
public class StateBean implements IStateBean
{  
   private static int number = 0;

   @PostConstruct
   void init()
   {
      number++;
      System.out.println("@PostConstruct: " + number);
   }

   @PreDestroy
   void destroy()
   {
      number--;
      System.out.println("@PreDestroy: " + number);  
   }
}

I do lookup in servlet for this bean

public class MyServlet extends HttpServlet
{  
   @Override
   public void doGet(final HttpServletRequest aRequest, final HttpServletResponse aResponse) throws ServletException, IOException
   {  
      IStateBean bean = new InitialContext().lookup("app-ear/StateBean/local");
      // ...
   }
}  

But each time new instance of StateBean is created.
I can call lookup twice but new instance of StateBean is created again

   @Override
   public void doGet(final HttpServletRequest aRequest, final HttpServletResponse aResponse) throws ServletException, IOException
   {  
      IStateBean bean1 = new InitialContext().lookup("app-ear/StateBean/local"); 
      IStateBean bean2 = new InitialContext().lookup("app-ear/StateBean/local"); // new instance is created
      // ...
   }  

I expect the same instance in the same http-session

Servlet mapping in web.xml

   <servlet>
      <servlet-name>MyServlet</servlet-name>
      <servlet-class>com.package.MyServlet</servlet-class>
   </servlet>  
   <servlet-mapping>
      <servlet-name>MyServlet</servlet-name>
      <url-pattern>*.html</url-pattern>
   </servlet-mapping>

回答1:

The EJB spec does not say, that multiple lookups will return the same instance of a stateful session bean. In opposite: It is even required for the server to create two different instances, to guarantee that every client gets his own instance on the server.

The EJB spec only says that while you're referencing a stateful session bean, it retains its internal state across multiple method invocations:

IStateBean bean = new InitialContext().lookup("app-ear/StateBean/local");
bean.myMethod1();
bean.myMethod2(); // affects the same EJB instance on the server

Note that this might NOT be the case when using stateless session beans. Here, the two method calls shown above might go to different instances on the server!