Skip Headers
Oracle® Application Server TopLink Application Developer's Guide
10g Release 2 (10.1.2)
Part No. B15901-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

Inheritance

Inheritance enables you to share attributes between objects such that a subclass inherits attributes from its parent class. OracleAS TopLink provides several methods to preserve inheritance relationships, and enables you to override mappings that are specified in a superclass, or to map attributes that are not mapped in the superclass. Subclasses must include the same database field (or fields) as the parent class for their primary key (although the primary key can have different names in these two tables). As a result, when you are mapping relationships to a subclass stored in a separate table, the subclass table must include the parent table primary key, even if the subclass primary key differs from the parent primary key.

This section describes OracleAS TopLink inheritance, and introduces several topics and techniques to leverage inheritance in your own applications, including:

For more information about implementing inheritance in code, see "Implementing Inheritance in Java".

Understanding Object Inheritance

Consider a simple database used by a courier company. It contains registration information for three types of vehicles: trucks, cars, and bicycles. For each vehicle type, your application requires the following information:

  • VID (Vehicle Identification)

  • LastMaint (mileage since last maintenance)

  • LoadCap (load capacity)

If these are all the attributes shared by all vehicles in the application, then these attributes must all appear in the super class, Vehicle. You can then build subclasses for each of the vehicle types that reflects their differences. For example, the Truck class may have an attribute indicating whether the local department of transportation considers it to be a commercial vehicle (NumAxles), the Car class may require a NumPass (number of passengers) attribute, and the Bicycle class, by virtue of its more limited range, may require a Location attribute. Through inheritance, each vehicle automatically inherits the basic vehicle information, but by being separate subclasses, also have unique characteristics.

Figure 3-6 Inheritance in a Courier Application

Description of inhrex.gif follows
Description of the illustration inhrex.gif

Representing Inheritance in the Database

You can represent inheritance in the database in one of two ways:

  • Multiple tables that represent the parent class and each child class

  • A single table that comprises the parent and all child classes

Figure 3-7 Inheritance in the Database in Individual Tables

Description of dbinhrt1.gif follows
Description of the illustration dbinhrt1.gif

If your database already represents the objects in the inheritance hierarchy this way, you can map the objects and relationships without modifying the tables. However, it is most efficient to represent all classes from a given inheritance hierarchy in a single table, because it substantially reduces the number of table reads and eliminates joins when querying on objects in the hierarchy.

Figure 3-8 Inheritance in the Database in a Single Table

Description of dbinhrt2.gif follows
Description of the illustration dbinhrt2.gif

To consolidate tables in the database this way, determine the class type of the objects represented by the rows in the table. There are two ways to determine class type:

  • If you can add columns to the database table, add a class indicator column that represents the vehicle class type (Truck, Car, or Bicycle).

    For more information about class indicators, see "Class Indicators".

  • If you cannot modify the table, build a class extraction method that executes an appropriate login to determine the class type.

    For more information about class extraction methods, see "Class Extraction Methods".

Class Types

The OracleAS TopLink inheritance hierarchy includes three types of classes:

Figure 3-9 Inheritance Hierarchy Class Types

Description of rtbrlf.gif follows
Description of the illustration rtbrlf.gif

Root Class

The root class stores information for all instantiable classes in its subclass hierarchy. By default, queries performed on the root class return instances of the root class and its instantiable subclasses. However, you can also configure the root class to return only instances of itself, without instances of its subclasses when queried. All class types beneath the root class inherit from the root class.

Branch Class

Branch classes have a persistent superclass and subclasses. By default, queries performed on the branch class return instances of the branch class and any of its subclasses. As with the root class, you can configure the branch class to return only instances of itself, without instances of its subclasses when queried. All classes below the branch class inherit attributes from the branch class, including any attributes the branch class inherits from classes above it in the hierarchy.

Leaf Class

Leaf classes have a persistent superclass in the hierarchy, but do not have subclasses. Queries performed on the leaf class return only instances of the leaf class.

Class Indicators

A class indicator is a mechanism for determining the class or type of an object. For example, a Person table may include an indication of whether the person represented by the table row is an Employee or a Manager. Use the class indicator to select the appropriate subclass to be instantiated from a set of available subclasses.

Class Indicator Field

A class indicator field is a number or string stored in a database table that indicates the class or type of an object. OracleAS TopLink uses this information to determine the correct type of object to instantiate when building an object from that data in the row. For example, an EMPLOYEE table may contain a field, the value of which indicates whether the employee is permanent or contract, and determines whether OracleAS TopLink instantiates a PermanentEmployee object or a ContractEmployee object.

You can use strings or numbers as values in the class indicator field in the database. The root class descriptor must specify how the value in the class indicator field translates into the class to be instantiated.

Class Indicators and Mappings

Class indicator fields do not have an associated direct mapping unless the mapping is set to read-only. Mappings defined for the write-lock or class indicator field must be read-only, unless the write-lock is configured not to be stored in the cache, and the class indicator is part of the primary key.

For more information about transformation mappings, see "Transformation Mappings".

Class Extraction Methods

Class extraction enables you to determine the correct class type to instantiate from a table that includes several classes. Unlike a class indicator, however, a class extraction method does not rely on a single column in the table to determine class type. Instead, you can apply logic to the information in several fields to determine class type.

This method is useful when you use a legacy database with a new application. Table 3-1 illustrates a sample use of the class extraction method.

Table 3-1 Sample Use of the Class Extraction Method

ID NAME JOB_TYPE JOB_TITLE
732 Bob Jones 1 Manager
733 Sarah Smith 3 Technical Writer
734 Ben Ng 2 Director
735 Sally Johnson 3 Programmer

The inheritance hierarchy is designed such that Employee is the root class, and Director is a branch class that inherits from Employee. All employees, other than directors, are represented as instances of Employee, but directors must be represented by an instance of the Director class. Because values other than 2 can appear in the JOB_TYPE field, you cannot use the class indicator mechanism of OracleAS TopLink for mapping this data.

To resolve this, add a class extraction method to the root class, Employee. The method executes custom logic to determine the correct class to instantiate. The method is static, returns a Class object, and takes DatabaseRow as a single parameter.

Example 3-24 Simple Class Extraction Method

// Return the Director class for TYPE values of 2,
// Employee class for any other value

public static Class getClassFromRow(DatabaseRow row) {
    if (row.get("JOB_TYPE").equals(new Integer(2)) {
        return Director.class;
    }
    else { return Employee.class;
    }
}

This simple case enables you to determine whether the selected person is of the Director class or the Employee class. You can also implement complex logic that combines information from several columns in the table to infer class type. For example, consider a table that represents vehicles in a municipal vehicle pool.

Table 3-2 Gross Vehicle Weight and Number of Axles Example

Gross Vehicle Weight Number Of Axles
2650 3
800 2
2730 2
2400 2
3580 4

Although there is no direct indication of vehicle type in the data, you can build logic into a class extraction method to infer the vehicle type. This is made easier if you are familiar with the available types in the database. In this example, you can use a class extraction method to implement the following logic:

  • If NumberOfAxles is greater than 2, then return the class HeavyTruck.

  • If NumberOfAxles is 2 or less and GrossVehicleWeight is greater than 1000, then return the class type PassengerVehicle.

  • In all other cases, return the class Motorcycle.

Example 3-25 Complex Class Extraction Method

public static Class getClassFromRow(DatabaseRow row) {
    if (row.get("NumberOfAxles").intValue()>2){
        return HeavyTruck.class;
    }
    else {
        if (row.get("GrossVehicleWeight").intValue()>1000) {
            return PassengerVehicle.class;
        }
        else { return Motorcycle.class;
        }
    }
}

In addition to implementing logic to determine object class, you can use class extraction methods to execute other methods unrelated to class determination. This is an unusual use for class extraction methods, but, provided that the method ultimately returns a class type, it is possible.

To implement the class extraction method in OracleAS TopLink Mapping Workbench, open the inheritance settings for the root descriptor in the subclass hierarchy (EMPLOYEE in this case), and select the class extraction method in the Use Class Extraction Method box.

Entity Bean Inheritance Restrictions

The following restrictions apply to entity beans when using inheritance:

  • The Home interfaces cannot inherit. The findByPrimaryKey method must be overloaded to have the correct return type, but this is not allowed. Because of this, inheritance is not applicable to the Home interfaces.

  • The primary key of the subclass must be the same as that of the parent class.

The Application Server EJB 1.1 and 2.0 CMP Advanced Examples illustrate inheritance. For more information, see the OracleAS TopLink Examples at <ORACLE_HOME>\toplink\doc\examples.htm.


Note:

Because the existing EJB specifications offer no implementation guidelines for inheritance, exercise caution when implementing inheritance—especially if EJB compliance is an issue for your application.