No, actually the client calls for create() and remove() do not necessarily correspond with the ejbRemove() or ejbCreate(). This allows the container to pool bean instances - since actual creation and destruction of beans are resource intensive tasks. When a client calls a create(), an idle stateless session bean (SLSB) may be retrieved from the pool to service the call if idle beans exist. Otherwise an actual bean instance will be created to meet the demand. Similarly, the client remove() may simply release the EJB back to the pool of available SLSBs if the pool of beans has not exceeded some limit. Otherwise the bean is destroyed if the limit has been exceeded - depending on the pooling algorithm. In most theoretical explanations, the EJB container is shown to manage an instance lifecycle and is separated from the client create() and remove() actions.
Hope that makes sense.
Thanks for the quick reply. Yes it does make sense.
However, the book I have about EJB, titled "Professional EJB" published by WROX which I usually find a very reliable source of information, excplicitly states: "The ejbRemove() method is invoked by the container before it ends the life of the session bean, either due to the client invoking a remove method, or the container deciding to timout the bean."
My problem is that ejbCreate is called often whereas ejbRemove is called never. Not even when I explicitly call remove on its reference.
So I wondered if this is something particular to JBoss (a bug maybe?) or if this is generally like this. After all they may argue you're not supposed to hold on to anything in a stateless session bean, so they don't bother to call ejbRemove at all.
OK. I guess we'll have to resort to book references. ;)
From Mastering Enterprise JavaBeans by Ed Roman:
EJB Object Decoupling
Because the beans are pooled and reused, they are decoupled from EJB objects. The beans can be reassigned at any time to another EJB object, depending on the container's strategy. Therefore, a new bean does not necessarily have to be created at the same time an EJB object is created. Rather, a bean can be taken from the available pool. If client load suddenly increases, more beans can be instantiated by the EJB container at any time. Similarly, the EJB container can destroy beans at any time.
create() and remove() are for creating and destroying EJB objects. This may not correspond with bean creation and destruction.
In this context, the observed JBoss operation is within expectations. This behaviour is also observable in WebSphere and SilverStream. Note, we are talking about SLSB.
SLSBs have a timeout. The client remove() is a nice way of signalling to the container that the bean is available for re-assignment - since the container has no notion of the length of time to complete execution of the business logic. If the bean hasn't been returned by the set time, the container forces the return - since an instance is single-threaded, this is necessary. ejbRemove() destroys the bean instance, which is useful for protecting the the valuable memory resource but its use is determined by the container.
The ejbRemove() method is invoked by the container before it ends the life of the session bean - Correct
due to the client invoking a remove method - Wrong
It is up to the container to decide when the session bean is created and removed. The specification is available from the Sun web site.
You should find that the session bean instance still exists after the client has called removed and gets reused for sebsequent clients.
I noted that JBoss 3.2.3 never calls ejbRemove!