Clearing instance variables in stateless session beans

Discussions

EJB programming & troubleshooting: Clearing instance variables in stateless session beans

  1. Does anyone know the best place to clear down instance vars in a stateless session bean, So when the next user picks up the bean from the pool, the vars are clear.

    This cannot be done in the ejbcreate or setSessionContext as these are only done once when the bean is put in the pool.

    Cheers..

  2. If you always call the .remove() on your SSB, you could do the cleardown in the ejbRemove() method.

    Cheers,
    Rick
  3. What kinds of variables are you using for your stateless sessions beans? The general practice is to discourage the use of variables to cache client conversation states (that is the job of stateful session beans). It is OK to have variables to cache references to resources, such as DataSource, Connection, etc. For those I assume you really don't want to set them to null when the beans are returned to the instance pool; otherwise it defeats the purpose of having them as instance variables, doesn't it?
  4. Thats right. Any references, I will keep. I just want to be thorough and make sure we have no data problems when the next user picks up the bean.

  5. The only thing I can think of is to have method called
    initialize() or something along that line and call that
    at the beginning of each business method.

    Pranab
  6. ejbRemove() should be called any time the bean is destroyed, whether the client calls EjbObject.remove() or the EJB container times out the bean. Therefore, do your cleanup in there.
  7. What's the point clearing instance variables in
    ejbRemove(). The bean is going to be destroyed any way.

    I thought that the issue had to do with having a hook to clear all isntance variables when a bean gets picked up from the the pool by the container and gets attached to the EJBObject when a business method is invoked by the client.

    ejbRemove() is invoked by the container. It's useful for relasing any resources that were obtained in ejbCreate().

    Pranab
  8. Remember SLSB is pooled. Yes the EJBObject is destroyed, not the bean class, which is returned to the pool and recycled. This behavior is the same as that of an entity bean. In the latter case you can place code in ejbActivate/ejbPassivate, but SLSB's lifecycle doesn't go through ejbActivate/ejbPassivate. Hence the best way to clear instance variables in SLSB (generally a bad idea to start with) is in ejbRemove, before the bean class gets put back to the instance pool.
  9. I thought ejbremove destroyed the bean, and therefore it won't be in the pool anymore.

    ejbremove is good for removing resources.
  10. I think I answered this question in an earlier discussion, but it always helps to keep it current.

    In a stateless session bean ejb.remove() does not remove the bean, it simply frees the session from the bean and puts it in the free pool, this is a time saving feature of most ejb containers as the container does not have to constantly create new beans, the number of beans kept in the pool is dependent on the cache setting in the deployment descriptor, well at least in weblogic it is in there.

    So calling ejb.remove() on a stateless session bean will not "remove" the bean, but you can put any cleanup code in the ejb.remove() method to make sure it is ready for next time.


    In contrast, calling ejb.remove() on entity bean should act like a delete SQL statement, in that it should remove the data that it is pointing to from the database.


    Hope this helps,

    Rich
  11. According to EJB spec (p.73) and OReily's "Enterprise Java Beans" (p. 192), when the client calls remove() on the EJBObject, it's not delegated to the ejbRemove() of the SLSB. The bean is simply placed back in the pool. The container calls ejbRemove() when it deems to necessary to destroy a SLSB to reduce the number of beans in the pool.

    So clearing instance variables in ejbRemove() is of no consequence.

    Moreover, I don't see the point of calling remove() from client. At the end of a business method call, the SLSB gets detached from the EJBObject and returned to the pool any way.

    If I have misunderstood anything, please clarify it.

    Pranab


     
  12. Pranab is absolutely CORRECT, calling ejb.remove() does not call the ejbRemove() method of a session bean. The only way to initialize a session bean is by creating an initialization method or by putting code into ejbCreate(), but remember ejbCreate() is only called when the session is first put into the cache and that session can be used over and over again until the container decides it has had enough of the session. I would suggest an initialization method, also I would re-evaluate the use of the stateless session bean to see if it makes sense to use, maybe a stateful session bean or entity bean is a better choice.

    Sorry for the confusion,

    Rich
  13. I ran a test using WebLogic 5.1 sp10. Yes, you are right, ejbRemove never gets called by the container between client invocations, as long as the bean instance stays alive in the instance pool. This is true even when EjbObject.remove is called at the end of each client invocation. ejbRemove is called when the container is ready to get rid of the bean instance completely, i.e., clears it out of the instance pool. Therefore, the take-home lesson is: never rely on instance variables in SLSB for client specific data! Only use them for caching shared resources.