This lesson explains how to create advanced Toplink mapping
types, including object type, aggregate object, direct collection, and many-to-many
mappings using EJBs.
This lesson should take about an hour to complete.
Viewing Screenshots
Move your mouse over this icon to show
all screenshots. You can also move your mouse over each individual icon to see
only the screenshot associated with it.
Overview
This lesson project expands the application in the introductory
lesson. In addition to the Employee,
Address, and PhoneNumber
classes from the introductory lesson (see TopLink Mappings Introductory Tutorial),
this lesson uses these classes:
EmploymentPeriod
- Defines the contract term for contractors and the hire date for ACME employees.
Each Employee class has an
EmploymentPeriod.
Responsibilities
- Each Employee has a collection of text that describes the employee's job.
Project
- Maintains information about a particular project and the people working
on it. The Project class contains two subclasses: LargeProject
and SmallProject. Each Employee
can be involved in more than one project.
TeamLeader
- Each Project can have a team leader (the Employee responsible for the project).
Manager
- Each Employee may have a manager and a collection of managed employees.
The following figure illustrates the object model for this
system:
You will improve the Employee Management System (built
in the introductory tutorial) to manage additional information such as the ability
to track employees' current projects, managers, and contract period.
Install the sample tables and classes for this lesson. Copy advanced.zip
to your hard drive and extract the files.
4.
Using SQLPlus, connect to an Oracle8i or higher database
as the tltutorial user, and run the advanced.sql
script. The script creates and populates tables in the tltutorial schema.
5.
Create a database connection in JDeveloper for the tltutorial user. Instructions
for creating a database connection in JDeveloper can be found in the lesson:
Installing
the Sample Schemas and Establishing a Database Connection. However,
instead of creating a connection named jdbc_tutorial_connection, create
a connection using the tltutorial connection name, specifying tltutorial
as both the username and password.
Use this procedure to create a new EJB 2.0 project, add the
necessary Java classes and ejb-jar.xml
files, and create a TopLink descriptor.
1.
In JDeveloper, select TopLinkTutorials workspace in the Navigator
pane (created in Creating a TopLink Mapping Project the Introductory Tutorial)
and select New from the File menu.
The New Gallery appears.
2.
In the Categories pane, select General >Projects. In
the Items pane, select TopLink Project.
Click OK. The Create TopLink-Enabled Project wizard appears.
3.
Review the information on the first page of the wizard and click Next.
Enter ejbEmployee as the project name.
Click Finish to create the project.
4.
Double-click TopLink Mappings in the Navigator.
The TopLink Mappings tab appears in the TopLink Mapping Editor, and the
TopLink Mappings descriptor appears in the Structure window.
5.
Now import the EJB classes used in the lesson.
In the Application Navigator pane, select the ejbEmployee project.
Select File > Import.
The Import dialog appears.
6.
Select EJB Deployment Descriptor (ejb-jar.xml) File and click
OK.
The Import EJB Descriptor wizard appears.
7.
Review the information on the first page of the wizard and click Next.
Ensure the ejbEmployee project is the project where the files will be
imported and click Next.
8.
Specify the following file locations, substituting the location where
you extracted advanced.zip
for <EXTRACT_LOCATION>:
Ensure the Target directory field points to the current project and click
Next.
9.
Select Import selected EJB's and files and choose the following:
Enterprise JavaBeans: Employee, Project, LargeProject, and SmallProject
Other Files: Address.java, EmploymentPeriod.java, PhoneNumber.java
Click Finish. Refer to the "EJB Deployment Descriptor Import
wizard" for additional information. JDeveloper automatically updates
the project source path and TopLink creates an EJB descriptor for each
class and an unmapped mapping for each attribute.
10.
Although the non-EJB classes have been added to the project, we have
not yet created TopLink descriptors for these classes.
Select TopLink Mappings in the Navigator pane.
Click Add or Remove Descriptors in the TopLink Mappings - Structure
window.
The TopLink Descriptors dialog appears.
11.
Select the following non-EJB classes and use the arrow button to move
them to the selected list:
Address
EmploymentPeriod
PhoneNumber
Click OK. Note: JDeveloper automatically created TopLink descriptors
for the EJB classes when you imported the ejb-jar.xml
file.
12.
From the File menu, choose Save All.
Step 2 - Associating
Descriptors to Database Tables
Associate the following classes to the corresponding database table:
EmployeeBean to TLTUTORIAL.EJB_EMPLOYEE LargeProjectBean to TLTUTORIAL.EJB_LPROJECT PhoneNumber to TLTUTORIAL.EJB_PHONENUMBER ProjectBean to TLTUTORIAL.EJB_PROJECT
TopLink can automatically map class attributes to similarly
named database tables and fields. This Automap wizard creates mappings only for
unmapped attributesit does not change previously defined mappings. You can
automap all of the classes in a project or package. You may also map classes individually.
Although the Automap wizard correctly maps most descriptors and attributes, you
may need to add or change some suggested mappings. In this step you will use the
Automap wizard to map the Address descriptor.
Select TopLink Mappings in the Navigator pane
and expand the Address descriptor in the Structure window.
2.
Right-click the Address descriptor in the Structure window and choose
Automap from the pop-up menu.
The Automap Wizard Welcome screen appears. Read the information and
click Next. You can also automap descriptors by clicking Automap
in the Structure Pane.
3.
Verify the Primary Table selection (TLTUTORIAL.EJB_ADDRESS) and click
Next.
4.
Verify the mapping type (Direct-to-Field) for each attribute in the Address
descriptor and click Next.
5.
Verify the following database fields for each attribute in the Address
bean:
city to TLTUTORIAL.EJBADDRESS.CITY country to TLTUTORIAL.EJBADDRESS.COUNTRY id to TLTUTORIAL.EJBADDRESS.ADDRESS_ID postalCode to TLTUTORIAL.EJBADDRESS.P_CODE province to TLTUTORIAL.EJBADDRESS.PROVINCE street to TLTUTORIAL.EJBADDRESS.STREET
Click Finish. The wizard automatically maps each attribute to
the appropriate database table.
Step 3- Create a One-to-One
Self Relationship that Implements Indirection
Indirection allows you to retrieve objects from the
database as needed. With indirection turned off, when an object is retrieved
from the database all the other objects that it references are also retrieved.
With indirection turned on, each object is retrieved from the database only
when asked for. Thus, using indirection can be a great performance benefit,
and is strongly recommended. Refer to the Oracle Application Server TopLink
Application Developer's Guide for more information.
You can implement indirection using
direct access or method access. For method access, TopLink requires additional
get and set methods that provide access to the value holders. For direct access,
TopLink can access the value holders directlythe additional get and set
methods are not required. The classes provided with this lesson already have
indirection implemented.
Additionally, some object models require a class to reference
another instance of the same class. In this lesson, the address
attribute in the Employee class
references another class, Address.
Thus, to map the address attribute and implement indirection, follow these steps:
1.
Expand the EmployeeBean in the Structure window. The Mapping
editor displays the TopLink descriptor information.
Note: Notice that some attributes (such as managedEmployees) are already
mapped. The TopLink Mapping editor reads these CMR mappings from the ejb-jar.xml
file. Use the EJB editor, not the TopLink Mapping editor, to modify these
relationships. These relationships are discussed later in the lesson.
2.
Click the address attribute of the Employee descriptor in the
Structure window.
TopLink displays the valid mappings for this attribute in the Mapping
editor.
3.
Choose One-to-One and click Map As.
The Mapping editor displays the information for a one-to-one relationship
to be specified. Because the address attribute is a CMP relationship,
TopLink adds a bean to the icon in the mapping. TopLink identifies both
CMR and CMP mappings in the TopLink Mappings - Structure window.
4.
On the General tab, select Address as the Reference Descriptor.
Select the Use ValueHolder Indirection option.
Click the Table Reference tab and select the EJB_EMPLOYEE_EJB_ADDRESS
table.
5.
Follow steps 1 through 4 above to map the following one-to-one attributes:
owner attribute in the PhoneNumber descriptor manager attribute in the Employee descriptor teamLeader attribute in the Project descriptor
The reference descriptor for these attributes is EmployeeBean.
Some object models require a class to reference another
instance of the same class. In this lesson, a manager can have a collection
of managed employees. These CMR mappings in the EmployeBean were created when
you imported the ejb-jar.xml
file. To complete the mappings, you must define the table references. To define
the managedEmployee attribute, follow these steps:
1.
Expand the EmployeeBean in the TopLink Mappings - Structure window.
The managedEmployees attribute
is already mapped as a CMR one-to-many mapping.
2.
Click the managedEmployees attribute of the Employee descriptor
in the Structure window.
Select the Use Indirection option, and choose Transparent.
3.
Click the Table Reference tab and select the EJB_EMPLOYEE_EJB_EMPLOYEE
table.
4.
Follow steps 1 through 3 above to map the phoneNumbers
attribute in the Employee descriptor using a one-to-many relationship.
With the TopLink Mapping editor, it is possible to spread
classes across two or more tables. In this lesson, the Employee class is stored
in multiple tables; although most information is in the EMPLOYEE table, each employee's
salary information is stored in the SALARY table. Follow these instructions to
map the Employee class to multiple tables:
Expand the EmployeeBean in the TopLink Mappings - Structure window.
Right-click the EmployeeBean in the Structure window and choose Advanced
Properties > Multitable Info from the context menu.
The Multitable Info tab appears in the Editor pane. You can also select
the Multi-Table Info tab by clicking Advanced Properties in the Structure
toolbar.
2.
In the Additional Tables area, click Add and add the EJB_SALARY
table.
In the Associated Via area, select Primary Key.
In the Primary Key Table Reference area, select Primary Keys Have Different
Names.
Select FK_EJB_SALARY_EMP_ID as the Table Reference.
3.
Now map the Employee's salary attribute as a direct-to-field
mapping to the salary field in the EJB_SALARY table.
4.
From the File menu, choose Save All.
Implementing Object Type Mappings
With the Mapping editor, you can match a fixed number of database
values to Java objects through object type mappings. In this lesson, each employee's
gender is stored as a single letter in the database field (M or F), but the
value is the full name (Male or Female). To map the gender attribute, follow
these steps:
Expand the EmployeeBean in the TopLink Mappings Structure pane.
Click the gender attribute of the Employee descriptor in the Structure
pane.
TopLink displays the valid mappings for this attribute in the Editor
pane.
2.
Choose Object-Type and click Map As.
3.
In the Database Field, select the GENDER field from the EJB_EMPLOYEE
table.
Select Character as the Database Type, and String as the
Object Type.
Click Add and create the following database mappings:
Database Value
Object Value
F
Female
M
Male
4.
From the File menu, choose Save All.
Implementing Aggregate Object
Type Mappings
In TopLink mappings, two objects are related by aggregation
if there is a 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 this project, the EmploymentPeriod is an aggregate descriptor, and the period
attribute is an aggregate object. Follow these steps to map an aggregate object:
Right-click the EmploymentPeriod descriptor and select Descriptor
Type > Aggregate Descriptor.
The descriptor's icon in the Structure pane changes to an aggregate descriptor.
You can also select the Aggregate Descriptor by clicking Descriptor Type
in the Structure toolbar.
2.
Map the startDate and EndDate attributes of the EmploymentPeriod as direct-to-field
mappings.
Note: The Database fields are not displayed because the aggregate descriptor
is not associated with a database table.
3.
Select the period
attribute of the EmployeeBean.
Choose Aggregate Mapping and click Map As.
4.
Use the Reference Descriptor drop-down list to choose the EmploymentPeriod
aggregate descriptor.
5.
Click the Fields tab and use the Fields drop-down list to map
each field as follows:
endDate - END_DATE startDate - START_DATE
6.
From the File menu, choose Save All.
Implementing Direct Collection
Mappings
Direct collection mappings store collections of Java objects
that are not TopLink-enabled. In this lesson, the responsibilities attribute is
a direct collection. To map a direct collection, follow these steps:
Select the responsibilities
attribute of the EmployeeBean in the Structure pane.
Choose Direct Collection and click Map As.
2.
To specify where to place the strings in the direct collection, use the
Target Table and Direct Field drop-down lists to select
the DESCRIP field
on the EJB_RESP databases table.
Select the Use Indirection option and choose Transparent.
3.
Click the Table Reference tab and select the FK_EJB_RES_EMP_ID
reference.
4.
From the File menu, choose Save All.
Implementing Many-to-Many Mappings
Many-to-many mappings represent relationships between a
collection of source objects and a collection of target objects. In this lesson,
the projects attribute uses a CMR many-to-many-mapping (for example, many employees
can have many projects). To map a many-to-many mapping, follow these steps:
Select the projects
attribute of the EmployeeBean descriptor in the Structure pane.
TopLink displays attributes as CMR many-to-many mappings (based on the
information in the ejb-jar.xml
file).
2.
Use the Relation Table drop-down list to choose the EJB_PROJ_EMP table (the class to map to).
Ensure that Use Indirection is selected.
Select Read Only for this attribute. Although multiple mappings
in this project use this same relation table, only one can be writable.
The teamMembers attribute
of the ProjectBean will be the writable mapping.
3.
Click the Source Reference tab and select the FK_EJB_PROJ_EMP_EMP_ID
table.
4.
Click the Target Reference tab and select the FK_EJB_PROJ_EMP_PROJ_ID
table.
Inheritance describes how a child class inherits the characteristics
of its parent class. TopLink uses multiple implementations to support database
inheritance. In this lesson, the LargeProjectBean and SmallProjectBean classes
inherit the characteristics of the ProjectBean class. Use the following procedures
to set the ProjectBean descriptor to implement inheritance, then enable the
two subclasses.
1.
Right-click the ProjectBean in the Structure pane choose Advanced
Properties > Inheritance from the context menu.
You can also select the Inheritance tab by clicking Advanced Properties
in the Structure toolbar.
2.
Ensure that Is Root Descriptor is selected.
Select the Use Class Indicator Field option, and use the dropdown
list to choose PROJ_TYPE.
Select Use Class Indicator Dictionary and use the Indicator Type
Browse button to choose a String type.
3.
Right-click SmallProject in the Structure pane choose Advanced
Properties > Inheritance from the context menu.
You can also select the Inheritance tab by clicking Advanced Properties
in the Structure toolbar.
4.
In the Parent Descriptor drop-down list, choose the ProjectBean
class.
5.
Repeat steps 3 and 4 for the LargeProjectBean descriptor.
6.
To complete the inheritance mappings, select the ProjectBean mapping
editor.
Click the Inheritance tab in the Editor pane.
7.
For each inherited descriptor, select the Include column.
Click Edit and enter an Indicator Value (S for SmallProject and
L for LargeProject).
8.
To complete the mappings, map the description, id, and
name attributes of the ProjectBean as direct to field mappings,
and map the budget attribute of the LargeProjectBean as a direct
to field mapping.
9.
Create Direct to Field mappings for the following attributes:
EmployeeBean attributes firstname, id, and lastname
LargeProjectBean attribute id
PhoneNumber attributes areacode, id, number, and
type
SmallProjectBean attribute id
10.
From the File menu, choose Save All.
Summary
This lesson explained how to use advanced Toplink mappings
and how to implement indirection and utilize inheritance. You may wish to deploy
the project using the deployment steps found in Mapping
Java Objects to Database Tables Using Toplink
Move your mouse over this icon to hide all screenshots