I have been trying to work out a resource problem we are having within the WebLogic server where resources are allocated but never seem to be released. We initialize the resource in setEntityContext() and release the resource when unsetEntityContext() is invoked. However, we are never seeing unsetEntityContext() invoked. We have tried several ways to make this happen. Would there be some reason we would not see output from the bean on unsetEntityContext(). I know that it must be invoked at some point (don't even see it at a graceful shutdown of the Weblogic server). Any thoughts? Thank you.
The trick here is that you will only see the method called when the pool is scaled down. Which might be tough to "force" with a load test. However, you would think you would see it when a container is shutting down.
Don't know what is going on there, ask BEA. However, there should be nothing wrong with instantiating resources in activate and then removing them in passivate. Is there a reason why your resources should not be gained / released in these methods?
The lifecycle of an entity bean seems to indicate to me that passivate and activate is where you would normally do this, unless there the penalty of acquiring / releasing the connection is how long it takes to do so. If it is a long process to acquire a connection, and a long time to release it, then activate and passivate don't seem to attractive - do they. Perhaps this is when you should consider putting the connection behind a pool and let beans share the pool, instead. Otherwise - I guess the only option is to go ahead and implement the finalize() method, If BEA won't fulfill the contract - why should you!!
From the EJB 2.0 spec (section 10.5.1): "The container can remove an instance in the pool by calling the unsetEntityContext() method on the instance."
I cannot see that there is a requirement to call this method when the container is closing down! (It may be a good idea to do so, but it's not a requirement...)
Same spec (section 10.6.2): "The class must not define the finalize() method." So this proposal is out of question!
So if unsetEntityContext() is never called and finalize is out of question, what can you do? My proposal is:
- Introduce a local stateless session bean to handle the calls to the resource.
- Use this SLSB from your entity bean.
- Allocate the resource in ejbCreate() of the SLSB.
- Release resources in ejbRemove().
This will secure the life cycle of your resources. (See section 7.8.1 of the spec.) The performance penalty is low when using a local SLSB. The instance pool of stateless session beans will (indirectly) be used as a resource pool
Thomas, what a great idea!
I agree finalize is out of the question, it was suggested tounge in cheek. Why not do file IO while we are at it?
However, I will reiterate that the spec is at least ambigous in the statement:
"The container can remove an instance in the pool by calling the unsetEntityContext() method on the instance."
Because terminating a pool means terminating the instances in the pool, I would agree that the spec does not appear to be demanding the method be called when shutting down the container.
As we see here, it is unfortunate it is not required, because expensive resource allocation becomes more difficult.
but to reiterate, your idea of using a stateless session bean is really good. Thanks for sharing.