ntity bean inheritance has a lot of confusion surrounding it because the EJB specification does not give any clear guidelines on this topic. EJB specification documents 2.0 and 2.1 say entity bean inheritance (i.e., an entity bean inheriting from another entity bean) will be considered in future specs.
Nevertheless, IBM’s WebSphere Application Server (WAS) supports EJB inheritance in conjunction with WebSphere Application Developer (WSAD). With this feature, you can define a type hierarchy for persistent objects that is much like the type hierarchies widely used for transient objects. This article sets clear guidelines for using inheritance in a WebSphere environment, and it examines various options supported by WebSphere for EJB inheritance. It details standard class inheritance and EJB inheritance, comparing their advantages and disadvantages. This guide also provides details regarding implementation and deployment changes, problems, and solutions.
WSAD supports two forms of inheritance:
- Standard class inheritance?The home interface, remote interface, or enterprise bean class inherits properties and methods from base classes that are not themselves enterprise bean classes or interfaces.
- EJB inheritance?An enterprise bean inherits properties (such as CMP fields and relationship roles), methods, and method-level assembly description attributes from another enterprise bean that resides in the same EJB module.
These two inheritance options have the following advantages and disadvantages:
- EJB inheritance is easy to implement using WSAD, but standard class inheritance has the advantage of being simple/clear Java inheritance.
- In the case of root-leaf mapping, EJB inheritance mapping may not perform as well as standard class inheritance because of the large SQL statements and numerous joins involved. In the case of single table mapping, the extra columns may cause some performance hitches.
- Key classes are common to all inherited enterprise beans (i.e., the key class in the child enterprise bean is identical to the key class in the parent enterprise bean).
- For standard class inheritance, the EJB references need to be set manually for child beans.
Before determining the best solutions for various requirements, let’s go over the implementation details that are common to all cases:
- When an inheritance relationship is defined between enterprise beans, all home methods that are not part of an association are copied to the child bean. In order to have specific create methods on subtypes without having to support the supertype create methods, the child Home interface will not extend the supertype enterprise bean’s Home interface.
- The bean class of the new child enterprise bean extends the bean class of the parent enterprise bean.
- If any of the parent bean methods or callback methods is overridden in the child method, the implementer has to call the parent method in the child implementation if required.
- The Local and Remote interfaces will extend the supertype enterprise bean’s remote interface.
- Key classes are common to all inherited enterprise beans. Therefore, the key class in the child enterprise bean is identical to the key class in the parent enterprise bean.
- You can add to the key only at the root bean.
- In case of standard class inheritance, the EJB references defined on the parent had to be copied manually to the child bean. With EJB inheritance, all references marked to the parent bean automatically transfer to child beans.
- All the beans referencing child beans automatically have references to parent beans and not vice versa. So the implementer has to ensure that all the references are changed to child if he needs to access a child (especially in the case of standard class inheritance, in which the parent bean would be deleted and all the references to it lost). Make sure the references are moved to child if you are moving to standard class inheritance.
By default, EJB inheritance hierarchies are mapped to a single table; that is, the base and all derived enterprise beans are mapped to the same database table. Additional options exist that support generating joined tables for the leaf enterprise beans.
To create an inheritance map, select the enterprise bean and the corresponding table. Just like in secondary tables, you need to have a primary-key to primary-key/foreign-key relationship. The rest of the beans in the inheritance structure are then mapped as a root/leaf inheritance map. You can regenerate the default map and schema using the Mapping wizard or by clicking Re-execute Mapping Commands in the Mapping editor.
The Discriminator column is used for distinguishing between the various entity beans stored in the table. Set this property in the Bean to the Table Strategy section on the Property view of the Mapping editor.
For standard class inheritance mapping, where you want to maintain the superclass mappings before deleting the super class deployment description, simply copy the mapping from the superclass EJB into the deployment description of the subclass EJB. Next, manually add the additional attribute to the subclass’s table and define the mapping for it.
For EJB inheritance, you need to deploy both the child and parent entity beans. In WSAD, the child entity bean definition sets the inheritance relationship. In standard class inheritance, removing the deployed parent EJB makes sense. In this scenario, avoid deploying the superclass EJB if they are not instantiated directly (This eliminates cluttering the JNDI tree with things that are never requested). So remove all the definitions in both deployment and mapping descriptions to the superclass EJB, and add the undeployed superclass EJB (home, remote, and bean class) as utility classes (e.g., using a Java Project in WSAD).
Note: When you add a child class and then delete the deployment description of a parent class, WSAD automatically removes the class inheritance code from the child class. So you have to be sure to maintain that code.
Inheritance Case Studies
This section examines different inheritance scenarios, suggesting when to choose standard or EJB inheritance for each according to your requirements.
Case 1: Inheritance with only one child bean and abstract parent
A single child bean, parent bean acts as just a template and it is never used/created as a sole entity bean. For example, consider a company that deals only with U.S. customers. It wants to use “Address” and extend it to USAddress (Figure 1 shows a class diagram for this scenario).
|Figure 1. Inheritance with Only One Child Bean and Abstract Parent|
This is a typical case for which you should use standard class inheritance. For Address, AddressBean would just be two Java classes and USAddress would be the actual entity bean. AddressBean’s home is not required now.
If your Address bean already exists, its deployment description has to be deleted. Again, before deleting the entity bean, you need to keep a copy of the database mapping
Now you can copy back the mapping descriptions, ejb-queries, and references.You already have a parent entity bean mapped to its table. Here are the steps you would follow:
- Copy the newly generated child entity beans code to ejbModulepackagename directory.
- Refresh and rebuild the project.
- Open ejb-jar.xml in a text editor, and replace the parent entity bean’s name with the child entity bean.
- Add additional cmp fields into this entity bean.
- Open the parent entity bean table configuration in the table editor.
- Change the table names to the child bean name, and add the additional required columns to this table.
- Open mapping in Mapping editor, and create the mapping between the renamed table and child bean. Also, you may be required to manually create mapping between new columns.
- Save everything and generate the deploy and RMIC code.
Case 2: Multiple child beans and abstract parent
A multiple child bean, parent bean act as just a template and are never used/created as a sole entity bean. You encounter this scenario in a lot of places, and you cannot use the solution provided in Case 1 for it. Deleting the parent entity bean would case the child beans to act like independent, non-related entity beans.
|Figure 2. Multiple Child Beans and Abstract Parent|
This case manifests itself in two ways:
- When two-child beans need to be connected only logically (i.e., they do not share the common persisted data), you remove the parent entity.
- When two children are not connected only logically through a common parent but also share common database columns for storing persistent data, you keep the parent entity bean but make it logically abstract so that it cannot be initiated. (Figure 2 shows an example in a class diagram.)
In scenario number 2, you have a parent Address bean that you already have created and deployed. Now you have two child entity beans: one for USAddress and another for RestOfWorldAddress (see Figure 2).
To make a parent entity bean logically abstract, make the following changes:
- Give Home a findByPrimaryKey method, but no create methods.
- Give HomeHelper a findByPrimaryKey, but no create and remove methods.
- Give HomePolicy the same methods as HomeHelper.
You would already have a parent entity bean mapped to its table. Here are the steps you would follow:
- Copy the newly generated child entity bean’s code to the ejbModulepackagename directory.
- Make the parent bean logically abstract (following the changes defined above).Refresh and rebuild the project.
- Open ejb-jar.xml and add the newly generated child entity beans to the project. Also, add any extra fields.
- Open ejb-jar.xml in the deployment description editor, go to the inheritance section, edit both the child entity beans, and select Inherits from supertype. This ensures that the cmp_ids used in ejb-jar.xml are common for all three entity beans. This may also add an additional ejbFindByPrimaryKey method, which has to be removed.
- Open parent entity bean table configuration in the table editor.
- Add additional required columns, and add an extra discriminator column.
- Open mapping in the Mapping editor, select Parent bean, and go to the property pane. Name the newly created column discriminator column, with the value “ParentBeanName”.
- Create the mapping between the parent table and child beans. Also, you may be required to manually create mapping between new columns. Make sure the values and column name for discriminator are the same for all three entity beans.
- Save everything and generate the deploy and RMIC code.
|Figure 3. Class Diagram for Case 3|
Case 3: Inheritance with one child bean, and parent bean
In this case, child and parent entity beans can be created and accessed independently. The standard class inheritance cannot help you in any way here. The only solution is to deploy both the parent and child entity beans independently. As shown in Figure 3‘s class diagram, both the Address entity bean and the EmployeeAddress entity bean can be used and created.
The solution for this scenario is quite similar to that for Case 2. You define the EmployeeAddress bean as a child bean in the inheritance section of ejb-jar.xml, and then map the child bean on the same or a different table depending upon the mapping technique you choose. The only difference between this and Case 2 is that the parent entity bean would also have the create methods. So you do not need to make the parent entity bean logically abstract. So all the steps for this transformation are the same as Case 2, except for Step 2 (which is not required).
|Figure 4. Class Diagram for Case 4|
Case 4: Inheritance with multiple child beans and parent bean
This case is very similar to Case 3?in fact, the solution to this case is the same as Case 3. Consider the case where you want to use EmployeeAddress for Employees, OfficeAddress for Offices, and Address for the rest of the addresses (see Figure 4).Here, you would select entity bean inheritance with Address as the parent bean and EmployeeAddress/OfficeAddress as the child beans. Again, you would use discriminator in this case.
Object-oriented Design for Your Beans
Using inheritance to design your beans gives you the real advantage of using object-oriented designing. Most application servers provide a process for inheriting session beans, but entity bean inheritance is not yet covered in the EJB specification. This article provided instructions for using entity bean inheritance in IBM’s WebSphere Application Server. The different scenarios presented give you an idea of how you can use inheritance for entity beans.