EJB Inheritance, Part 1
2. Local Interfaces
The local interfaces have a similar design. The local interface BaseCustomer
extends EJBLocalObject, and the sub-interfaces extend BaseCustomer.
Here's the code:
Example 4. Local interface for BaseCustomer
//Removed for readability: package, imports.
public interface BaseCustomer extends EJBLocalObject {
public String getCustomerID();
public String getName();
public void setName(String newName);
public int getPoints();
public int addPoints(int purchaseAmount);
public int redeemPoints(int zone);
}
Example 5. Local interface for PlatinumCustomer
//Removed for readability: package, imports.
public interface PlatinumCustomer extends basecustomer.BaseCustomer
{
public String getCharity();
public void setCharity(String newCharity);
}
Note the new accessor method in PlatinumCustomer, to handle the charity's
name. We could have added new business methods, too.
3. Local Home Interfaces
If there's a single place where inheritance clashes with entity EJBs, it's
the home interfaces. They can't extend each other! Why is that? Because
of the way the specification is written. Let's take, for example, the case
of a create method. The specification says the return type of all create
methods must be the business interface (either the local or remote interface).
In a theoretical base home interface, the returned type would be the base
local interface. If you try to write a home sub-interface, the return type
would be wrong.
We'll have to go through some workarounds in order to impose inheritance-like
behavior for the methods of the home interface. There are three kinds of
methods that can be found in home interfaces:
-
Create methods
-
Finders
-
Home methods
We will later see how these methods can be conceived so that they emulate
inheritance. But for now, write the home interfaces using the regular technique;
they should extend EJBLocalHome.
4. create & postCreate Methods
Emulating inheritance in create and postCreate methods
is relatively easy. Simply put, all you'll have to do is to call the right super.ejbCreate()
and super.ejbPostCreate() in the subclasses. Here's an example based on
the RTM system:
Example 6. BaseCustomerBean
//...
public abstract class BaseCustomerBean implements EntityBean {
//...
public String ejbCreate(String customerID, String name)
throws CreateException
{
setCustomerID(customerID);
setName(name);
setPoints(0);
return null;
}
public void ejbPostCreate(String customerID, String name)
{
}
//...
}
Example 7. PlatinumCustomerBean
//...
public abstract class PlatinumCustomerBean extends basecustomer.BaseCustomerBean
{
//...
public String ejbCreate(String customerID, String name, String charity)
throws CreateException
{
super.ejbCreate(customerID,name);
setCharity(charity);
return null;
}
public void ejbPostCreate(String customerID, String name, String charity) {
super.ejbPostCreate(customerID,name);
}
//...
}
Here, the subclass' ejbCreate() calls the superclass' ejbCreate() to
initialize most of the fields, and then it initializes the remaining fields.
This works because creation is handled by your code. ejbPostCreate() works
the same way. Even though the base class' ejbPostCreate() is empty, it
is good practice to call super.ejbPostCreate() just in case this changes
in the future.
Note that our create methods in the subclasses override the ones in
the base class. But subclasses can create new create methods, with different
parameters. This works fine too, as long as fields are initialized properly.