Some reader favorites:
EJB fundamentals and session beans
Create a scrollable virtual desktop in Swing
Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API
Although this strong model frees developers to concentrate on the business logic instead of inventing and building transactionality and database mappings themselves, it is too rigid for distributed computing in the real world. The real world's sluggish networks slow the performance of several cooperating business objects running on different machines. Also, simple data entry by a user creating or editing a business object can run too slowly if, for example, a frontend JavaServer Pages (JSP) engine is not running on the same machine as the business object, or if a person is using a Java client on a workstation.
In general, if an entity bean is not in the same location as the process performing the task and the network is a bottleneck, either the process must come to the data, or the data must come to the process. An example of the former option is a session bean that performs a certain task on behalf of a remote client. The classic client-server model is an implementation of the latter alternative, but I use another approach that I call astral cloning.
In this article, I will explain how to use an entity bean implementation as a client-side cached version of the bean. The implementation runs outside the application server, having an "outer-container" experience, hence the term astral clone. Many developers use some kind of caching to make a distributed system perform. Astral cloning provides a better version of the solution proposed by Thomas Davis in "Direct Network Traffic of EJBs" (JavaWorld, November 1999; see Resources for a direct link) with respect to encapsulation of business logic into one object and transparency to the client-side code.
Note: This article presumes that you are familiar with EJB programming. Also, I explain astral cloning and its consequences as it relates to container-managed entity beans only.
To explain how to implement astral clones, I will first illustrate how an entity bean typically works.

Figure 1. Standard invocation through a stub
Figure 1 shows how a client calls several methods on a generated stub that implements the bean interface. Using RMI, the stub delegates these calls to the container, which is generated to run the bean implementation's instances. Finally, the container calls the bean implementation's right instance.
Instead of calling a remote bean, we can create a local copy of this bean -- an astral clone -- using the following steps:
getAstralClone() in the entity bean interface
this)
getAstralClone() on the remote entity bean, a bean's clone is returned through serialization/deserialization (standard RMI behavior)
Figure 2 illustrates how the astral clone operates.

Figure 2. Invocation of an astral clone
Working on an astral clone produces the following advantages:
get(), set(), or other methods on the bean.
Let's take a look at a simple container-managed PersonBean example:
public interface Person {
public String getName() throws RemoteException;
public void setName(String aName) throws RemoteException;
public int getAge() throws RemoteException;
public setBirthDay(Calendar aDate)
throws SomeValidationException, RemoteException;
}
Note that the Person interface cannot be used as an EJB interface, because it does not extend EJBObject. I have separated the functional requirements of a person from the technical implementation details, like using EJB. The
following code fragment declares the bean interface:
public interface EJBPerson extends Person, EJBObject {
// return an astral clone
public Person getAstralClone() throws RemoteException;
}
The bean implementation PersonBean defines the getAstralClone() method, in addition to the other Person methods, like so:
// return an astral clone
public Person getAstralClone() throws RemoteException {
return this;
}
To make this piece of code work, PersonBean has to implement the following two interfaces:
java.io.Serializable, so that it can return itself as the return value of the RMI call
Person, to (1) compile the previous code fragment and (2) enable the client to talk with PersonBean as an astral clone in the same way that it talks with the EJBPerson stub
Figure 3 shows the relationships between the various interfaces and classes.

Figure 3. Class diagram of the PersonBean example
My company used the astral cloning technique in a suite of components we developed for a Dutch bank's treasury. For accessing static data -- entity beans that do not change often, like currencies and holiday calendars -- the technique has drastically improved the performance of the trading framework and realtime rates calculation engine, which heavily depend on this data. Using this practical experience, in the sections below I will elaborate on the nuts and bolts of astral cloning, including:
EntityContextWhen working with astral clones, you must first figure out what to do with the EntityContext, as described in the javax.ejb package:
TheEntityContextinterface provides an instance with access to the container-provided runtime context of an entity enterprise bean instance. The container passes theEntityContextinterface to an entity enterprise Bean instance after the instance has been created.
(You can find a link to the full javadoc for EntityContext in Resources below.)
Every entity bean must have a javax.ejb.EntityContext instance variable. However, the container-provided value this variable holds cannot be expected to function outside the container
(or the value might not be serializable, and therefore not transportable using RMI). So you must declare this variable as
follows:
private transient EntityContext context;
Whenever you want to reference context, you must first check if it is null. If the context returns null, you are dealing with an astral clone.
After initialization, the astral clone should have the same state as its contained original bean after the container activates
and loads the bean; both now are ready to be used by the client. In the case of container-managed entity beans, the container
calls the ejbLoad() method immediately after populating the instance variables with values from the database. You might have placed statements
in this method to make the instance ready for usage.
But nothing calls ejbLoad() automatically on the astral clone after creation by deserialization. Therefore, you must call this method on the clone after
retrieving the clone with the getAstralClone() method. However, I prefer to leave the ejbLoad() method empty, and use the lazy initialization programming idiom to execute the omitted statements.
For example, if the person table in the database has a field partner_id, then you might want to initialize a partner instance variable in the ejbLoad() method with an EJB reference to the partner bean, and use the partner variable in the rest of the bean. However, it is better to leave ejbLoad() empty, and use a getPartner() method in the rest of the bean, which looks something like this:
private Person getPartner() throws FinderException, RemoteException {
if (partner_id == null) {
return null;
}
// only retrieve the partner once, and only if needed
if (partner == null) {
partner = getPersonHome().findByPK(new PersonPK(partner_id));
}
return partner;
}
Instance variables in your entity bean, like the previously mentioned partner variable, are not part of the persistent state, but do contain already calculated results. You should declare such variables
either as nontransient, with serializable calculated values, or as transient, with values lazily recalculated when accessed.
EntityContext javadocFree Download - 5 Minute Product Review. When slow equals Off: Manage the complexity of Web applications - Symphoniq
![]()
Free Download - 5 Minute Product Review. Realize the benefits of real user monitoring in less than an hour. - Symphoniq