In most typical scenarios, entity beans need to hold references to other entity beans, be it one to one, one to many, etc. So how to we deal with this when we are using Bean Managed Persistence (BMP)? The most straight forward way is to initialize all your references in ejbLoad(). That way your entity bean will be ready to use with all references intact, once activated. Now consider the effects of instantiating all your references in ejbLoad. The loading of one entity bean would cause the loading of potentially hundreds of other entity beans! If all you wanted to do was something simple like getting its Details Object, this is a tremendous waste of resources.
The solution is to lazy load your entity beans. This is a flashy term that basically means don't instantiate and save a reference to another entity bean until you need to.
For example, consider a forum messaging system. A Message entity bean should have a reference to its containing thread, the User that posted it, and its parent Message (if it is a reply). To lazy load your beans, you would have the following code in your "getThread" or your "getUser" methods:
public Thread getThread() throws EJBException {
if ( this.myThread != null )
{
return this.myThread;
}
try //to lazy initialize the thread this Message is in
{
this.myThread = (Thread) this.aThreadHome.findByPrimaryKey( new ThreadPK(this.threadPK) );
return this.myThread;
}
catch( Exception e )
{
//log error here
throw new EJBException( e );
}
}
public User getUser() throws EJBException {
if ( this.myUser != null )
{
return this.myUser;
}
try //to lazy initialize
{
this.myUser = (User) this.aUserHome.findByPrimaryKey( new UserPK(this.userPK) );
return this.myUser;
}
catch( Exception e )
{
//log error here
throw new EJBException( e );
}
}
Where this.myThread, this.myUser are references to a Thread and User Entity bean. Now don't forget to clear out all your references in ejbPassivate, since these references are specific to this particular entity bean instance:
/**
* Called by Container. Releases held resources for
* passivation.
*/
public void ejbPassivate() {
//nullify our other entity bean references since they may reflect
//reflect bean refernces of a different entity bean
this.myThread = null;
this.myUser = null;
}
Using this strategy will result in more memory efficient, faster Enterprise Java Bean applications!
-
Lazy Load Entity Bean References (9 messages)
- Posted by: Floyd Marinescu
- Posted on: July 13 2000 13:30 EDT
Threaded Messages (9)
- Lazy Load Entity Bean References by Brian Matalus on July 20 2000 16:36 EDT
- Lazy Load Entity Bean References by Floyd Marinescu on July 20 2000 16:58 EDT
- Lazy Load Entity Bean References by Mike Park on November 21 2000 12:07 EST
- Lazy Load Entity Bean References by Vlastimil Elias on January 30 2001 08:26 EST
-
Lazy Load Entity Bean References by Appaji Y on April 19 2001 06:34 EDT
-
Lazy Load Entity Bean References by Appaji Y on April 19 2001 06:53 EDT
- Lazy Load Entity Bean References by Idhayachandran Manivannan on May 02 2001 03:20 EDT
-
Lazy Load Entity Bean References by Appaji Y on April 19 2001 06:53 EDT
-
Lazy Load Entity Bean References by Keith Elliott on May 05 2001 01:31 EDT
- Lazy Load Entity Bean References by Willow Mcguigan on June 05 2002 06:44 EDT
-
Lazy Load Entity Bean References by Appaji Y on April 19 2001 06:34 EDT
- Lazy Load Entity Bean References by Vlastimil Elias on January 30 2001 08:26 EST
-
Lazy Load Entity Bean References[ Go to top ]
- Posted by: Brian Matalus
- Posted on: July 20 2000 16:36 EDT
- in response to Floyd Marinescu
This strategy can be combined with the ValueObject pattern to pretty effectively minimize resource utilization at runtime.
The ValueObject would contain other uninstantiated ValueObjects. At the time they are first used, they would be fully realized and initialized. We introduce some latecy here, but by intelligently selecting the granularity of our ValueObjects... we can make this latency negligable.
Also by introducing a "projection" metaphor to the ValueObject, we can control during the request for data the amount(number of fields) of data that we will get back at any one time.
Thoughts?
bmatalus@fusionally.com -
Lazy Load Entity Bean References[ Go to top ]
- Posted by: Floyd Marinescu
- Posted on: July 20 2000 16:58 EDT
- in response to Brian Matalus
Brian,
What do you mean by a "projection metaphor"?
Also, how would a ValueObject (or Details Object, as we call them here on TheServerSide), know to lazy initialize its references to other value objects? This would require access to the EJB API's, which would defeat the purpose of the data encapsulation provided by the Details Object.
Am I misunderstanding your architecture?
Floyd -
Lazy Load Entity Bean References[ Go to top ]
- Posted by: Mike Park
- Posted on: November 21 2000 12:07 EST
- in response to Floyd Marinescu
Floyd,
This sound like a great pattern and I intend to use it in my BMP for a project I'm on but I have a question. I'm fairly new to EJB and I beleive I know them failry well but I'm having trouble with these 2 lines:
this.myThread = (Thread) this.aThreadHome.findByPrimaryKey( new ThreadPK(this.threadPK) );
this.myUser = (User) this.aUserHome.findByPrimaryKey( new UserPK(this.userPK) );
I understand that this.myUser/myThread are member variables of the Message object, I just don't understand the last bit...are you casting the Message object to be a Thread/User object and accessing an EJBHome Interface reference stored with in that object for the findbyPrimaryKey();
Perhaps a complete example with source code would explain this better.
Mike
-
Lazy Load Entity Bean References[ Go to top ]
- Posted by: Vlastimil Elias
- Posted on: January 30 2001 08:26 EST
- in response to Mike Park
Mike
this.myThread = (Thread) this.aThreadHome.findByPrimaryKey( new ThreadPK(this.threadPK) );
This is not casting Message object to Thread object. I thing you are right this.myThread is member variables of the Message object. this.aThreadHome is member variable of Message object too and here is stored reference to EJBhome object of Thread EJB. Then findByPrimaryKey method of this member variables (EJBhome object for Thread EJB) is called and the result is casted to Thread.
Vlastik -
Lazy Load Entity Bean References[ Go to top ]
- Posted by: Appaji Y
- Posted on: April 19 2001 06:34 EDT
- in response to Vlastimil Elias
hello,
can u show me how myThread variable is initialized or declared in your entity bean.
I want to know what would be best framwork or way to maintain relations among my BMP entity beans.If i have ejb-ref in my DD , and use home references in my ejbload()for lazy reference.Is this mechanism works potentially to save from loading long hierarchical relations.
Then what is the differece calling other entity beans by looking up the entity beans that directly referred in DD and looking up entity beans that are in other containers.
Please can u explain me how is this ejb-ref helps me for managing my BMP entity bean internal relations.
Appaji. -
Lazy Load Entity Bean References[ Go to top ]
- Posted by: Appaji Y
- Posted on: April 19 2001 06:53 EDT
- in response to Appaji Y
Also I want to know is this a performance issue to store home reference in other entity beans and use it for lazy reference since this becomes a remote call to other entity bean. Can i make this possible in a session bean wrapping entity beans and mentioning all referred entity beans references ejb-ref in session bean DD.
Can anyone comment on this.
Appaji. -
Lazy Load Entity Bean References[ Go to top ]
- Posted by: Idhayachandran Manivannan
- Posted on: May 02 2001 15:20 EDT
- in response to Appaji Y
Hi appaji
We are showing in the DD about the referred Bean is beacuse the container will lookup for u and keep the connection to that bean always.
Also,We can't make Socket connections to the outside world from the EJB.But when u make the lookup,u have to make a Scoket connection.To avoid this,the container will do all for u if u just give in ejb-ref in DD.
by
idhaya -
Lazy Load Entity Bean References[ Go to top ]
- Posted by: Keith Elliott
- Posted on: May 05 2001 13:31 EDT
- in response to Vlastimil Elias
I understand that you should only obtain an EJB object when you need it. This is the main concept in lazy loading, if I understand things.
But what about home interfaces? Where should you do the JNDI lookup to establish the home interface? Often times, I establish the home interface just before I find the EJB object that I need. Is this OK? What are other good alternatives? How expensive is it to create a home interface?
More specifically, let's say I have a Session bean that calls other EJBs. One method in my session bean needs to find a User EJB. Should I establish the UserHome reference in the method right before I need it? If not, what are good alternatives?
Beyond Session beans, I often ask myself the same questions when writing client applications. You could make the home interface a class variable accessible to all methods. Or you could create the home interface right before you need it within individual methods.
Anyone have some thoughts? Thanks for any insight! -
Lazy Load Entity Bean References[ Go to top ]
- Posted by: Willow Mcguigan
- Posted on: June 05 2002 06:44 EDT
- in response to Keith Elliott
Read about Service Locator pattern.
Willow