The problem is worse in EJB 2.x as the container has no idea when a client has finished using a bean and hence the bean can hang around in memory until it times out, when it’ll be removed. In the meantime the container receives additional calls from the client creating more stateful beans and using even more memory.
One of the features added to EJB3 to alleviate this problem is the @Remove annotation. The purpose of this annotation is to inform the container that the client has finished with the bean and it can be removed from memory once the current method has completed.
Use of the @Remove can be demonstrated using a simple (and yes, contrived) order placement stateful bean. In this scenario, we’re buying a bunch of stuff by adding items, identified by their item id, to a stateful session bean. In the scenario, once we’ve added all the items to our order, we can either place or cancel the order.
Hence, the stateless session bean will have an addItem(...) method that looks something like this:
public void addItem(long itemId)
In our scenario we call this method multiple times.
Once we’ve completed selecting items, we can complete the order calling a method like this:
public Long confirmOrder()
Note that the @Remove annotation is used here to inform the container that the client has completed their work and that the bean can be removed from memory. Also, in our order placement scenario, the client can also choose to cancel the order:
public Long cancellOrder()
This demonstrates that you can use the @Remove annotation on several methods in your stateful EJB at each possible scenario endpoint.