Skip Headers

Oracle9iAS TopLink Tutorials
Release 2 (9.0.3)

Part Number B10062-01
Go To Documentation Library
Home
Go To Solution Area
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Go to previous page Go to next page

2
Advanced Tutorial

In this advanced tutorial, we will improve the ACME Employment Management System (built in the introductory tutorial) to manage additional information. You will update the introductory application with new project information and reuse existing components from previous applications.

You will also learn how to:

This advanced tutorial will add the ability to track employees' current projects, managers, and contract period. You will reuse components from the introductory tutorial.

In addition to the Employee, Address, and PhoneNumber classes from the introductory tutorial (see "Overview"), the advanced tutorial uses these classes:

Figure 2-1 illustrates the object model for the advanced tutorial.

Figure 2-1 The Advanced Tutorial Object Model

Text description of advmodel.gif follows.

Text description of the illustration advmodel.gif

Creating the Database Schema

The advanced ACME employee system stores the employee data in the following database tables. To use this tutorial, create these tables in your database application. Table 2-9 describes how each class relates to the database tables.

The column types listed here are generic; the actual column types depend on the database used.

Table 2-1 The EMPLOYEE Table   
Column name Column type Details

EMP_ID

NUMERIC(15)

Primary key

F_NAME

VARCHAR(40)

L_NAME

VARCHAR(40)

ADDR_ID

NUMERIC(15)

GENDER

CHAR(1)

START_DATE

DATE

END_DATE

DATE

START_TIME

TIME

END_TIME

TIME

MANAGER_ID

NUMERIC(15)

VERSION

NUMERIC(15)

Table 2-2 The SALARY Table
Column name Column type Details

EMP_ID

NUMERIC(15)

Primary key

SALARY

NUMERIC(10)

Table 2-3 The ADDRESS Table 
Column name Column type Details

ADDRESS_ID

NUMERIC(15)

Primary key

COUNTRY

VARCHAR(80)

STREET

VARCHAR(80)

CITY

VARCHAR(80)

PROVINCE

VARCHAR(80)

P_CODE

VARCHAR(20)

Table 2-4 The PHONE Table
Column name Column type Details

EMP_ID

NUMERIC(15)

Primary key

AREA_CODE

CHAR(3)

P_NUMBER

CHAR(7)

TYPE

VARCHAR(15)

Primary key

Table 2-5 The PROJECT Table
Column name Column type Details

PROJ_ID

NUMERIC(15)

Primary key

DESCRIP

VARCHAR(200)

PROJ_NAME

VARCHAR(30)

PROJ_TYPE

CHAR(1)

LEADER_ID

NUMERIC(15)

VERSION

NUMERIC(15)

Table 2-6 The LPROJECT Table
Column name Column type Details

PROJ_ID

NUMERIC(15)

Primary key

BUDGET

NUMERIC(10,2)

MILESTONE

TIMESTAMP

Table 2-7 The RESPONS Table
Column name Column type Details

EMP_ID

NUMERIC(15)

Primary key

DESCRIP

VARCHAR(200)

Table 2-8 The PROJ_EMP Table Between PROJECT and EMPLOYEE
Column name Column type Details

EMP_ID

NUMERIC(15)

Primary key

PROJ_ID

NUMERIC(15)

Primary key

Table 2-9 Relationships Between Classes and Database Table  
Column Class Attribute Database Type Java Type

EMPLOYEE

Employee

    EMP_ID

id

NUMERIC(15)

BigDecimal

    F_NAME

firstName

VARCHAR(40)

String

    L_NAME

lastName

VARCHAR(40)

String

    ADDR_ID

address

NUMERIC(15)

Address

    not applicable

phoneNumbers

not applicable

Vector

    GENDER

gender

CHAR(1)

String

    START_TIME

normalHours[0]

TIME

Time

    END_TIME

normalHours[1]

TIME

Time

    MANAGER_ID

manager

NUMERIC(15)

Employee

    not applicable

managedEmployees

not applicable

Vector

    not applicable

projects

not applicable

Vector

    see Employment Period

period

not applicable

EmploymentPeriod

SALARY

Employee

    EMP_ID

not applicable

NUMERIC(15)

not applicable

    SALARY

salary

NUMERIC(10)

int

EMPLOYEE

EmploymentPeriod

    START_DATE

startDate

DATE

Date

    END_DATE

endDate

DATE

Date

RESPONS

Employee

    EMP_ID

not applicable

NUMERIC(15)

not applicable

    DESCRIP

responsibilitiesList

VARCHAR(200)

String

    PROJECT

LargeProject and SmallProject

    PROJ_ID

id

NUMERIC(15)

BigDecimal

    DESCRIP

description

VARCHAR(200)

String

    LEADER_ID

teamLeader

NUMERIC(15)

Employee

    PROJ_NAME

name

VARCHAR(30)

String

    PROJ_TYPE

not applicable

CHAR(1)

not applicable

    VERSION

not applicable

NUMERIC(15)

not applicable

LPROJECT

LargeProject

    PROJ_ID

not applicable

NUMERIC(15)

not applicable

    BUDGET

budget

NUMERIC(10,2)

double

    MILESTONE

milestoneVersion

TIMESTAMP

TimeStamp

ADDRESS

Address

    ADDRESS_ID

id

NUMERIC(15)

BigDecimal

    COUNTRY

country

VARCHAR(80)

String

    STREET

street

VARCHAR(80)

String

    CITY

city

VARCHAR(80)

String

    PROVINCE

province

VARCHAR(80)

String

    P_CODE

postalCode

VARCHAR(20)

String

PHONE

PhoneNumber

    AREA_CODE

areaCode

CHAR(3)

String

    P_NUMBER

number

CHAR(7)

String

    EMP_ID

owner

NUMERIC(15)

Employee

    TYPE

type

VARCHAR(15)

String

PROJ_EMP

*Relation Table*

    PROJ_ID

not applicable

NUMERIC(15)

not applicable

    EMP_ID

not applicable

NUMERIC(15)

not applicable

Creating a New Project

  1. Create a new project for the Advanced Tutorial as described in "Creating a New Project".

    • For the database name, use ADVANCED_TUTORIAL_DB.

    • For the project name, use Advanced Tutorial.

  2. Set the project's class path to include the oracle.toplink.tutorials.advanced package. See "Setting the Project's Classpath".

  3. Enable the following classes in the oracle.toplink.tutorials.employee package and generate a TopLink descriptor for each Java class as described in "Generating the Class Definitions":

    • Address

    • Employee

    • EmploymentPeriod

    • LargeProject

    • PhoneNumber

    • Project

    • SmallProject

    Table 2-9 shows how the classes relate to the database tables.

  4. Log into the database as described in "Logging into the Database" to create or import the database information.

    Select one of the following methods to add database information:

    Refer to Table 2-1 through Table 2-8 for complete database information.

Mapping Classes to Tables

Map the each Java class in the Advanced tutorial to a database table as described in "Mapping Classes to Tables".

Map this class... To this database table...

Address

ADDRESS

Employee

EMPLOYEE

LargeProject

LPROJECT

PhoneNumber

PHONENUMBER

Project

PROJECT

Ensure that the primary keys are correctly indicated, as specified in Table 2-1 through Table 2-8.


Note:

A warning message appears indicating that you have not yet mapped the attributes. This will be addressed later in the tutorial


Using the Automap Tool

TopLink can automatically map class attributes to similarly named database. This Automap function only creates mappings for unmapped attributes - it does not change previously defined mappings.

You can automap classes for an entire project or for specific tables.


Note:

Although Automap correctly maps most one-to-one and direct-to-field mappings, you should examine each mapping for valid and correct information. You may need to add or change some mappings.


To Automap the Address descriptor:
  1. Choose the Address class in the Project Tree pane and click on the Descriptor Info tab in the Properties pane.

  2. In the Associated Table drop-down list, select the ADDRESS table.

    You must associate the class with a table before using the Automap tool.

  3. Right-click on the Address class in the Project Tree pane and select Automap from the pop-up menu.

    You can also automap descriptors by selecting Selected > Automap from the menu.

The system automatically maps each attribute to the appropriate database table. Do not Automap any other classes. You will manually map these classes later in this tutorial.

Implementing Indirection

Indirection allows you to retrieve objects from the database as needed.

Using indirection can be a great performance benefit and is strongly recommended. See the Oracle9iAS TopLink Mapping Workbench Reference Guide for more information.

Preparing Java Code for Indirection

To prepare your object model for indirection, you must alter the application slightly:

Indirection can be implemented using direct access or method access.

If the instance variable returns a Vector instead of an object then the value holder should be defined in the constructor as follows:

addresses = new ValueHolder(new Vector());

In the following examples, the Employee class uses indirection with method access for its one-to-one mapping to Address. The class definition is modified so that the address attribute of Employee is a ValueHolderInterface instead of an Address. In both examples, the application uses the getAddress() and setAddress() methods to access the Address object.

Example 2-1 Indirection Examples

The following example illustrates code before using indirection.

protected Address address;
   public Employee() {
      address = null;
   }
   public Address getAddress() {
      return address;
   }
   public void setAddress(Address address) {
      this.address = address;
   }
   

The following example illustrates the same code after using indirection.

protected ValueHolderInterface address;
   public Employee() {
      address = new ValueHolder();
   }
   public Address getAddress() {
      return (Address)address.getValue();
   }
   public void setAddress(Address address) {
      this.address.setValue(address);
   }
   

The indirection example could also use method access instead of direct access. This would be implemented by adding getAddressValueHolder() and setAddressValueHolder() methods.

Implementing Indirection in the Mapping Workbench

After modifying the code, update the TopLink Mapping Workbench descriptors to use indirection.

To implement indirection in the Workbench:
  1. Map the one-to-one and one-to-many mappings for each class as normal.

  2. On the General tab for each mapping, select the Use Indirection option.

    Figure 2-2 General Tab of a Mapping

    Text description of 11empatt.gif follows.

    Text description of the illustration 11empatt.gif

Implementing Indirection in the Tutorial

The following attributes in the Advanced tutorial sample code have been implemented using ValueHolderInterfaces:

Employee

PhoneNumber

Project

When you create mappings for these attributes, be sure to enable the Use Indirection option.

Implementing a One-to-one self Relationship

Some object models require a class to reference another instance of the same class. In the advanced tutorial, the Manager attribute in the Employee class references another employee (see Figure 2-1).

To map the manager attribute:
  1. Click on the Employee's manager attribute in the Project Tree pane, then click the One-to-one mapping button One-to-one Mapping button. in the mapping toolbar.

    The Properties pane displays the appropriate information for a one-to-one relationship to be specified.

  2. Use the Reference Descriptor drop-down list in the to select Employee as the reference descriptor.

    Figure 2-3 One-to-one Mapping General Tab

    Text description of 11mpmgr.gif follows.

    Text description of the illustration 11mpmgr.gif

  3. Select the Use Indirection option. See "Implementing Indirection in the Tutorial".

  4. Click the Table Reference tab.

    Figure 2-4 One-to-one Mapping Table Reference Tab

    Text description of 11manref.gif follows.

    Text description of the illustration 11manref.gif

  5. Create a new table reference by clicking the New button.

  6. In the New Reference Dialog, create a reference whose:

  7. Select EMPLOYEE_EMPLOYEE (created in step 5 from the Table Reference drop-down list.

  8. Click the Add button to define the foreign key fields.

  9. Click on Save Save Project button. in the toolbar or select File > Save Project to save the project.

Creating Other One-to-one Mappings

The Advanced tutorial also includes a one-to-one mapping for the following attributes:

Create these mappings as shown in "Creating One-to-one Mappings Between Objects". Refer to Table 2-9 for the correct relationships. Enable indirection for each of these mappings, as indicated in "Implementing Indirection in the Tutorial".

Implementing a One-to-many Self-relationship

Some object models require a class to reference another instance of the same class. In the advanced tutorial, a manager can have a collection of managed employees (see Figure 2-1).

To map the managedEmployee attribute:
  1. Click on the Employee's managedEmployees attribute in the Project Tree pane, then click the One-to-many mapping button One-to-many Mapping button. in the mapping toolbar.

    The Properties pane displays the appropriate information for a one-to-many relationship to be specified.

  2. Use the Reference Descriptor drop-down list to choose Employee.

    Figure 2-5 One-to-many Mapping General Tab

    Text description of 1mmanemp.gif follows.

    Text description of the illustration 1mmanemp.gif

  3. Select the Use Indirection option, and choose ValueHolder. See "Implementing Indirection in the Tutorial".

  4. Click the Table Reference tab. Use the Table Reference drop-down list to select the EMPLOYEE_EMPLOYEE table (previously created in "To map the manager attribute:").

    • Click the Add button on the Table Reference tab to add a foreign key relationship.

    • Set the Source (foreign key) field to MANAGER_ID.

    • Set the Target (primary key) field to EMP_ID.

      Figure 2-6 One-to-many Mapping Table Reference Tab

      Text description of 1mmantab.gif follows.

      Text description of the illustration 1mmantab.gif

  5. Click on Save Save Project button. in the toolbar or select File > Save Project to save the project.

Creating Other One-to-many Mappings

The Advanced tutorial also includes a one-to-many mapping for the phoneNumbers attribute in the Employee descriptor. Create this mapping as shown in "Creating One-to-many Mappings". Refer to Table 2-9 for the correct relationship.

Enable indirection for this mapping, as indicated in "Implementing Indirection in the Tutorial".

Using Multiple Tables

In TopLink, it is possible to spread classes across two or more tables. In the advanced tutorial, the Employee class is stored in multiple tables: although most information is in the EMPLOYEE table, salary information is stored in the SALARY table.

To map the Employee class to multiple tables:
  1. Click on the Employee descriptor in the Project Tree pane.

  2. Click on the Multi-table Info tab in the Properties pane.

    If the Multi-table info tab is not visible, right-click on the Employee descriptor and select Set Advanced Properties > Multi-table Info from the pop-up menu.

  3. In the Additional Tables pane, click on Add and add the SALARY table.

    Figure 2-7 Multi-table Info Tab

    Text description of multitab.gif follows.

    Text description of the illustration multitab.gif

  4. Click on Save Save Project button. in the toolbar or select File > Save Project to save the project.

Implementing Object Type Mapping

In TopLink, you can match a fixed number of database values to Java objects through object type mappings. In the advanced tutorial, each employee's gender is stored as a single letter in the database field (i.e., M or F), but the value is the full name (i.e., Male or Female).

To map the gender attribute:
  1. Expand on the Employee descriptor in the Project Tree pane.

  2. Select the gender attribute and click on the Object-type Mapping button Object-type Mapping button. in the mapping toolbar.

    Figure 2-8 Object-type Mapping Tab

    Text description of otmap.gif follows.

    Text description of the illustration otmap.gif

  3. In the Database Field, select the GENDER field from the EMPLOYEE table.

  4. Select Character as the Database Type and String as the Object Type.

  5. Click on Add and create the following database mappings:

    Database Value Object Value

    F

    Female

    M

    Male

  6. Click on Save Save Project button. in the toolbar or select File > Save Project to save the project.

Implementing an Aggregate Object

In TopLink, two objects are related by aggregation if there is one-to-one relationship between the objects and all the attributes of the second object can be retrieved from the same table(s) as the owning object. In the advanced tutorial, the EmploymentPeriod is an aggregate descriptor and the period attribute is an aggregate object.

To map an aggregate object:
  1. Click on the EmploymentPeriod descriptor in the Project Tree pane.

  2. Click on the Aggregate Descriptor button Aggregate Descriptor button. in the mapping toolbar. The descriptor's icon in the Project Tree pane changes to an aggregate descriptor Aggregate Descriptor icon. .

  3. Map the startDate and EndDate attributes of the EmploymentPeriod as direct-to-field mappings.


    Note:

    The Database Field fields are disabled because the aggregate descriptor is not associated with a database table.


  4. Expand the Employee descriptor in the Project Tree pane.

  5. Select the period attribute of the Employee descriptor.

  6. Click on the Aggregate Mapping button Aggregate Mapping button. in the mapping toolbar.

    Figure 2-9 Aggregate Mapping General Tab

    Text description of aggobj.gif follows.

    Text description of the illustration aggobj.gif

  7. Use the Reference Descriptor drop-down list to select the EmploymentPeriod aggregate descriptor.

  8. Click on the Fields tab.

    Figure 2-10 Aggregate Mapping Fields Tab

    Text description of aggobjdt.gif follows.

    Text description of the illustration aggobjdt.gif

  9. Use the Fields drop-down list to map each field as follows:

    • endDate - END_DATE

    • startDate - START_DATE

  10. Click on Save Save Project button. in the toolbar or select File > Save Project to save the project.

Implementing a Direct Collection Mapping

Direct collection mappings store collections of Java objects that are not TopLink-enabled. In the advanced tutorial, the responsibilitiesList attribute is a direct collection.

To map a direct collection:
  1. Expand on the Employee descriptor in the Project Tree pane.

  2. Click on the responsibilitiesList attribute of the Employee descriptor.

  3. Click on the Direct Collect button Direct Collection Mapping button. in the mapping toolbar.

  4. To specify where to place the strings in the direct collection, use the Target Table and Direct Field drop-down lists to specify the DESCRIP field on the RESPONS databases table.

  5. Select the Use Indirection option and choose ValueHolder. See "Implementing Indirection in the Tutorial".

    Figure 2-11 Direct Collection Mapping General Tab

    Text description of dctab.gif follows.

    Text description of the illustration dctab.gif

  6. Click the Table Reference tab, and add a new table reference by clicking the New button.

    • Create a reference named RESPONS_EMPLOYEE, with a source table of RESPONS and target table of EMPLOYEE and click OK.

    • In the Table Reference drop-down list, select the RESPONS_EMPLOYEE.

    • Click the Add button on the Table Reference tab to add a foreign key relationship.

    • Set the Source (foreign key) field to EMP_ID (from the RESPONS table).

    • Set the Target (primary key) field to EMP_ID (from the EMPLOYEE table).

  7. Click on Save Save Project button. in the toolbar or select File > Save Project to save the project.

Implementing a Many-to-many Mapping

Many-to-many mappings represent relationships between a collection of source objects and a collection of target objects. In the advanced tutorial, the projects attribute uses a many-to-many-mapping (for example, many employees can have many projects).

To map a many-to-many mapping:
  1. Expand the Employee descriptor in the Project Tree pane.

  2. Click on the projects attribute of the Employee descriptor.

  3. Click on the Many-to-many Mapping button Many-to-many Mapping button. in the mapping toolbar.

  4. Use the Reference Descriptor drop-down list to select the Project descriptor.

  5. Use the Relation Table drop-down list to select the PROJ_EMP table (the class to map to).

  6. Ensure that the Use Indirection field is selected. See "Implementing Indirection in the Tutorial".

    Figure 2-12 Many-to-many Mapping General Tab

    Text description of mmmap.gif follows.

    Text description of the illustration mmmap.gif

  7. Click the Source Reference tab, and add a new reference by clicking the New button.

    • Create a new reference named PROJ_EMP_EMPLOYEE, with a source table of PROJE_EMP and target table of EMPLOYEE, and click OK.

    • In the Table Reference drop-down list, select the PROJ_EMP_EMPLOYEE reference.

    • Click the Add button on the Source Reference tab to add a foreign key relationship.

    • Set the Foreign Key field to EMP_ID (from the PROJ_EMP table).

    • Set the Primary Key field to EMP_ID (from the EMPLOYEE table).

  8. Click the Target Reference tab, and add a new reference by clicking the New button.

    • In the Table Reference drop-down list, select the PROJ_EMP_PROJECT reference.

    • Click the Add button on the Source Reference tab to add a foreign key relationship.

    • Set the Source Field field to PROJ_ID (from the PROJ_EMP table).

    • Set the Target Field field to PROJ_ID (from the PROJECT table).

  9. Click on Save Save Project button. in the toolbar or select File > Save Project to save the project.

Implementing Inheritance

Inheritance describes how a child class inherits the characteristics of its parent class. TopLink uses multiple implementations to support database inheritance.

In the advanced tutorial, the LargeProject and SmallProject classes inherit the characteristics of the Project class. Use the following procedures to set the Project descriptor to implement inheritance, then enable the two subclasses.

To implement inheritance in the Project descriptor:
  1. Click on the Project descriptor in the Project Tree pane.

  2. Click on the Inheritance tab in the Properties pane.

    If the Inheritance tab is not visible, right-click on the Project descriptor and select Advanced Properties > Inheritance from the pop-up menu or Selected > Advanced Properties > Inheritance from the menu.

  3. Ensure that the Is Root Descriptor field is selected.

  4. Select the Use Class Indicator Field option and use the drop-down list to select PROJ_TYPE.

  5. Select the Use Class Indicator Dictionary field and use the Indicator Type drop-down list to select a String type.

To implement inheritance in each subclass:
  1. Click on the SmallProject descriptor in the Project Tree pane.

  2. Click on the Inheritance tab in the Properties pane.

    If the Inheritance tab is not visible, right-click on the Project descriptor and select Advanced Properties > Inheritance from the pop-up menu or Selected > Advanced Properties > Inheritance from the menu.

  3. In the Parent Descriptor drop-down list, select the Project class.

  4. Click on Save Save Project button. in the toolbar or select File > Save Project to save the project.

Repeat this procedure for the LargeProject descriptor.

To complete the inheritance:
  1. Click on the Project descriptor in the Project Tree pane.

  2. Click on the Inheritance tab in the Properties pane.

  3. For each descriptor:

Implementing a Transformation Mapping

Use transformation mappings for specialized translations between how a value is represented in Java and in the database. The method takes a database row as an argument and are called whenever an object is written to the database. The method returns the value from the object that should be written to the field.

In the advanced tutorial, the transformation method corresponds to a single argument method on the Employee class and extracts the values from the fields and places them into the NormalHours array.

To map the normalHours attribute:
  1. Expand on the Employee descriptor in the Project Tree pane.

  2. Click on the normalHours attribute of the Employee descriptor.

  3. Click on the Transformation Mapping button Transformation Mapping button. in the mapping toolbar.

  4. Click on the Add button to create the following Object->Field Methods:

    • Database Field: START_TIME, Method: getStartTime

    • Database Field: END_TIME, Method: getEndTime

  5. Use the Database Row -> Object Method drop-down list to select the bulidNormalHours method.

    Figure 2-14 Transformation Mapping Tab

    Text description of trmapdbr.gif follows.

    Text description of the illustration trmapdbr.gif

  6. Click on Save Save Project button. in the toolbar or select File > Save Project to save the project.

Mapping the Remaining Attributes

The remaining attributes for each descriptor are simple direct-to-field mappings. Use Table 2-9 to map each attribute.

Generating Code

To use your project with the Foundation Library, you must either generate deployment XML or export the project to Java source code.

In this tutorial, we will create a deployment XML file that can be read in at runtime. The code generator creates a single subclass that can be used instead of reading directly from the files.

To export to Java source code:
  1. Right-click on the project in the Project Tree pane and select Export Project to Java Source from the pop-up menu. The Choose an Export File window appears.

    You can also export the project by selecting File > Export to Java Source or Selected > Export to Java Source from the menu.

  2. Select a directory location and file name (.java) and click OK.

Congratulations! You have completed the Advanced Tutorial and are now familiar with the TopLink's advanced topics and functions.

A completed version of this tutorial is included with a standard installation of TopLink in the following directory:

<INSTALL_DIR>\workbench\demos\employee\EmployeeDemo.mwp


Go to previous page Go to next page
Oracle
Copyright © 2002 Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Home
Go To Solution Area
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index