I am working on a project which has 1 session bean and 3 entity beans. The session bean wraps the entity beans and acts as a Facade.
Inside the session bean, it has a business method which does the JNDI look up for the three entity beans, such as:
public collection businessmethod()
EntityBean1Home h1 = (EntityBean1Home)ctx.lookup("EntityBean1");
EntityBean2Home h2 = (EntityBean2Home)ctx.lookup("EntityBean2");
EntityBean3Home h3 = (EntityBean3Home)ctx.lookup("EntityBean3");
Since the lookup is very expensive in terms of performance, is there anyway to do the lookup once, save it and reuse it later. I tried to put the lookup in Constructor, it doesn't work(NullPointerException).
Any input is highly appreciated.
Hi there Gene,
This is quite a thing u mentioned there ....ne'er really gave much thought ti that but what i figure is that there is only one way to solve this problem ..... why dun u try to serialize the handle to the home interfaces and write it to a file or some place(some storage) and then when u want to reuse the handle, u can use the serialized handle to construct an object from it. By now u must have realized that i am originally a CORBA guy and the concept that i am talking bout rt now is the IOR concept in CORBA.
I guess this is one way..and i surely wud like to know if there are more..
In the ejb discriptor you can try increasing the idel time out to a high value you are comfortable with and then cache store the home interfaces you looked up in the beans session context.
When the bean finshes servicing a client it is unbound from the client and is free to service the next request. Richard Monson Haefel in his book Enterprise Java Bean says that we can store information in instance variables and resue it as long as the client does not make the assumption that it is being serviced by the same bean.
When a bean is created three operations are performed on it.
1. Class.newInstance() is called
2. SessionBean.setSessionContext() is called.
3. Finally a no argument ejbCreate() is invoked.
Refer your vendors documentation for further details.
I would be careful with what you are suggesting however.
The process that you are describing is only for the initiation of beans into the free pool. Beans in the free pool are used to handle find(...), create(...), and home(...) methods. They are not used for processing on an EJB with a given primary key.
If you need to use the home stubs in one of the methods listed above, then creating them in teh setSessionContext(...) might work. However, if you are merely using them in a business method then this is way overkill. You could potentially have many references to home stubs in your EJB objects when it isn't necessary to have them.
If you create the reference in the setSessionContext(...) method, then you will be holding a home stub reference while the object is in the free pool AND while the object is in the ready state. Using the values that you specified above, that would be a maximum of 1100 references to home stubs (up to 100 in the free pool if the container filled it up plus the 1000 that could potentially be used by EJBs in the ready state).
If the only location for using the home stubs is in a business method, create those references in the ejbActivate() method. You HAVE to trust your application server vendor to activate objects (moving them from the pool to the ready state) only when it absolutely necessary. Many containers will migrate objects to the ready state in a variety of manners, thus increasing overall performance. By delaying the storing of the home stubs as private attributes, you will be squeezing extra performance out of your system.
But Tyler, in his case he has a session bean looking up the entity, so it would seem to me that he is much better off looking up the object in ejbCreate() which will only occur once, then storing references to the home interfaces as private transient members. The only issue would be passivation, and you could then re-lookup the home interfaces at ejbActivate(). If this was an entity holding the reference I would agree totally with what your suggesting.
The idea of storing serialized handles on disk as suggested by someone on this thread has me shivering in my boots.
Internet Applications Division
i am agree with dave best way is to keep all ur lookup into
ejbCreate() i have designed the sessionn bean as a facade
pattern which talk to 8 entity beans.
I misread the original post... I thought he had an entity bean looking up the other entity beans. Yeah... definitely makes sense to do it in ejbCreate(...) with a session bean.
However, if he chose to go with an entity store references to the other entities then all of my blabbing makes sense. =)
There is no need to declare the home interface variables transient. Check the EJB1.1 spec. paragraph [6.4.1]. Although the stubs are not Serializable it is the responsibility of the Container to handle activation/passivation of these values.
I always forget about 6.4.1 since our stubs are serializable/externalizable but Stephen is indeed correct. You do not need to mark these fields as transient they must be handles by the container.
Internet Applications Division
I think you should call the lookup methods as part of ejbActivate(). Store the references to the home stubs as private, non-persistent attributes of your class.
ejbActivate() is called on an entity bean when it is moved from the pool (where it is naked and has no identity) to the ready state (where it is given a PK). So, ejbActivate() is typically only called once for the lifetime of a given PK's duration in memory.
This should provide good performance.