Oracle Fusion Middleware Developer's Guide for Oracle TopLink 11g Release 1 (11.1.1) Part Number B32441-03 |
|
|
View PDF |
This chapter describes how to configure a relational mapping.
This chapter includes the following sections:
For information on how to configure TopLink mappings options common to two or more mapping types, see Chapter 121, "Configuring a Mapping".
For information on how to create TopLink mappings, see Chapter 120, "Creating a Mapping".
Table 28-1 lists the types of relational mappings that you can configure and provides a cross-reference to the type-specific chapter that lists the configurable options supported by that type.
Table 28-1 Configuring Relational Mappings
For more information, see the following:
Table 28-2 lists the configurable options shared by two or more relational mapping types.
Table 28-2 Common Relational Mapping Options
You can associate an object attribute with a database field.
Table 28-3 summarizes which relational mappings support this option.
Table 28-3 Relational Mapping Support for Database Field
Mapping | How to Use Oracle JDeveloper | How to Configure a Database Field Using TopLink Workbench |
How to Use Java |
---|---|---|---|
![]() |
|
|
|
![]() |
|
|
When choosing the database field, you must consider Java and database field type compatibility.
TopLink supports the following Java types:
java.lang
: Boolean
, Float
, Integer
, String
, Double
, Long
, Short
, Byte
, Byte[ ]
, Character
, Character[ ]
; all the primitives associated with these classes
java.math
: BigInteger
, BigDecimal
java.sql
: Date
, Time
, Timestamp
java.util
: Date
, Calendar
While executing reads, the mappings in Table 28-6 perform the simple one-way data conversions that Table 28-4 describes. For two-way or more complex conversions, you must use converters (see Section 27.2.2, "Converters and Transformers").
The mappings in Table 28-3 also allow you to specify a null value. This may be required if primitive types are used in the object, and the database field allows null
values. For more information, see Section 121.5, "Configuring a Default Null Value at the Mapping Level".
Table 28-4 Type Conversions Provided by Direct-to-Field Mappings
Java type | Database type |
---|---|
|
NUMBER, NUMERIC, DECIMAL, FLOAT, DOUBLE, INT, SMALLINT, BIT, BOOLEAN |
|
BOOLEAN, BIT, SMALLINT, NUMBER, NUMERIC, DECIMAL, FLOAT, DOUBLE, INT |
|
VARCHAR, CHAR, VARCHAR2, CLOB, TEXT, LONG, LONG VARCHAR, MEMO The following types apply only to Oracle9: NVARCHAR2, NCLOB, NCHAR |
|
BLOB, LONG RAW, IMAGE, RAW, VARBINARY, BINARY, LONG VARBINARY |
|
TIME |
|
DATE |
TIMESTAMP |
Support for oracle.sql.TimeStamp
TopLink provides additional support for mapping Java date and time data types to Oracle Database DATE
, TIMESTAMP
, and TIMESTAMPTZ
data types when you use the Oracle JDBC driver with Oracle9i Database or later and the Oracle9Platform
in TopLink.
In a direct-to-field mapping, you are not required to specify the database type of the field value; TopLink determines the appropriate data type conversion.
Table 28-5 lists the supported direct-to-field mapping combinations.
Table 28-5 Supported Oracle Database Date and Time Direct-to-Field Mappings
Java Type | Database Type | Description |
---|---|---|
|
|
Full bidirectional support. |
|
Full bidirectional support. |
|
|
Full bidirectional support. |
|
|
|
Full bidirectional support. |
|
Full bidirectional support. |
|
|
Full bidirectional support. |
|
|
|
Full bidirectional support. |
|
Full bidirectional support. |
|
|
Nanoseconds are not stored in the database. |
|
|
|
Full bidirectional support. |
|
Full bidirectional support. |
|
|
Milliseconds are not stored in the database. |
|
|
Native SQL or binding gives Calendar timezone. Note: The TIMESTAMP database value has no timezone – the Calendar object provides the local timezone by default. If the database is not in this timezone, you must obtain the database timezone by some other means and update the Calendar object accordingly. For this reason, TIMESTAMPTZ may be a better choice. |
|
|
Native SQL or binding stores timezone; standard SQL is based on the local timezone. |
|
|
Neither timezone nor milliseconds are stored in the database. |
Note that some of these mappings result in a loss of precision: avoid these combinations if you require this level of precision. For example, if you create a direct-to-field mapping between a java.sql.Date
attribute and a TIMESTAMPTZ
database field, there is no loss of precision. However, if you create a direct-to-field mapping between a java.sql.Timestamp
attribute and a DATE
database field, the nanoseconds or milliseconds of the attribute are not stored in the database.
Use this procedure to select a specific database field for a direct mapping.
Select the direct mapping attribute in the Navigator. Its properties appear in the Editor.
Click the General tab. The General tab appears.
Figure 28-1 Direct Mapping General Tab, Database Field Option
Use the Database Field field to select a field for this direct mapping. You must have previously associated the descriptor with a database table as described in Section 23.2, "Configuring Associated Tables".
Note:
For direct-to-field mappings of an aggregate descriptor (see Section 23.6, "Configuring a Relational Descriptor as a Class or Aggregate Type"), this field is for display only and cannot be changed.In relational mappings that extend oracle.toplink.mappings.ForeignReferenceMapping
, attributes reference other TopLink descriptors–not the data source. You can select any descriptor in the project.
Table 28-6 summarizes which relational mappings support this option.
Table 28-6 Relational Mapping Support for Reference Descriptor
Mapping | How to Use Oracle JDeveloper | How to Configure a Reference Descriptor Using TopLink Workbench |
How to Use Java |
---|---|---|---|
One-to-one (see Section 27.5, "One-to-One Mapping") |
![]() |
|
|
Variable one-to-one (see Section 27.6, "Variable One-to-One Mapping") |
![]() |
|
|
One-to-many (see Section 27.7, "One-to-Many Mapping") |
![]() |
|
|
Many-to-many (see Section 27.8, "Many-to-Many Mapping") |
![]() |
|
|
Aggregate collection (see Section 27.9, "Aggregate Collection Mapping") |
|
|
|
Aggregate object (see Section 27.12, "Aggregate Object Mapping") |
![]() |
|
|
To specify a reference descriptor for a relational mapping, use this procedure.
Select the mapped attribute in the Navigator. Its properties appear in the Editor.
Click the General tab. The General tab appears.
Figure 28-2 General Tab, Reference Descriptor Field
Use the Reference Descriptor field to select the descriptor referenced by this relationship mapping.
Note:
For aggregate mappings the Reference Descriptor must be an aggregate. See Section 23.6, "Configuring a Relational Descriptor as a Class or Aggregate Type" for more information.For variable one-to-one mappings, the Reference Descriptor must be an interface. See Chapter 32, "Configuring a Relational Variable One-to-One Mapping" for more information.
You can specify a reference descriptor that is not in the current TopLink Workbench project. For example, to create a mapping to an Employee
class that does not exist in the current project, do the following:
Add the Employee
class to your current project. See Section 116.2, "Working with Projects".
Create the relationship mapping to the Employee
descriptor.
Deactivate the Employee
descriptor. See Active and Inactive Descriptors.
When you generate the deployment XML for your project, the mapping to the Employee
class will be included, but not the Employee
class.
Batch reading can be used in most of the relational mappings. This feature should be used only if it is known that the related objects are always required with the source object.
Table 28-7 summarizes which relational mappings support this option.
Table 28-7 Relational Mapping Support for Batch Reading
Mapping | How to Use Oracle JDeveloper | How to Configure Batch Reading Using TopLink Workbench |
How to Configure Batch Reading Using Java |
---|---|---|---|
One-to-one (see Section 27.5, "One-to-One Mapping") |
|
|
|
One-to-many (see Section 27.7, "One-to-Many Mapping") |
|
|
|
Many-to-many (see Section 27.8, "Many-to-Many Mapping") |
|
|
|
Direct collection (see Section 27.10, "Direct Collection Mapping") |
|
|
|
Direct map (see Section 27.11, "Direct Map Mapping") |
|
|
|
Aggregate object (see Section 27.12, "Aggregate Object Mapping") |
|
|
|
To use batch reading in a relationship mapping, use this procedure:
Select the mapped attribute in the Navigator. Its properties appear in the Editor.
Click the General tab. The General tab appears.
Figure 28-3 General Tab, Batch Reading Option
To specify that this mapping using batch reading, select the Batch Reading option.
Example 28-1 shows how to use a DescriptorCustomizer
class to add batch reading to a mapping.
Example 28-1 Query Optimization Using Batching
public void customize(ClassDescriptor descriptor) {
OneToManyMapping phoneNumbersMapping = new OneToManyMapping();
phoneNumbersMapping =
(OneToManyMapping)descriptor.getMappingForAttributeName("phones");
phoneNumbersMapping.useBatchReading();
// add mapping to descriptor
descriptor.addMapping(phoneNumbersMapping);
}
You can configure TopLink to maintain collections in order by query key.
Table 28-8 summarizes which relational mappings support this option.
Table 28-8 Relational Mapping Support for Query Key Order
Mapping | How to Use Oracle JDeveloper | How to Configure Query Key Order Using TopLink Workbench |
How to Configure Query Key Order Using Java |
---|---|---|---|
Many-to-many (see Section 27.8, "Many-to-Many Mapping") |
|
|
|
One-to-many (see Section 27.7, "One-to-Many Mapping") |
|
|
|
Aggregate collection (see Section 27.9, "Aggregate Collection Mapping") |
|
|
|
To specify the order of a mapping's query keys, use this procedure:
Select the mapped attribute in the Navigator. Its properties appear in the Editor.
Click the Ordering tab. The Ordering tab appears.
Field | Description |
---|---|
Query Key | Specify the query key to order by.
Click Add to add query keys to, or Remove to remove query keys from the ordering operation. Click Up or Down to change the sort order of selected query keys. |
Order | Specify if TopLink orders the selected query key in Ascending or Descending (alphabetical) order. |
Example 28-2 shows how to use the DescriptorCustomizer
class to add complex ordering to a mapping.
Example 28-2 Configuring Query Key Order
public void customize(ClassDescriptor descriptor) {
OneToManyMapping phoneNumbersMapping = new OneToManyMapping();
phoneNumbersMapping =
(OneToManyMapping)descriptor.getMappingForAttributeName("phones");
phoneNumbersMapping.addAscendingOrdering("areaCode");
ExpressionBuilder phone =
phoneNumbersMapping.getSelectionQuery().getExpressionBuilder();
phoneNumbersMapping.getSelectionQuery().addOrdering(
phone.get("type").toUpperCase().ascending());
// add mapping to descriptor
descriptor.addMapping(phoneNumbersMapping);
}
Note:
You can provide the same functionality by using a descriptor amendment method (see Section 13.6, "Using the Descriptor Amendment Methods").A foreign key is a combination of one or more database columns that reference a unique key, usually the primary key, in another table. Foreign keys can be any number of fields (similar to a primary key), all of which are treated as a unit. A foreign key and the parent key it references must have the same number and type of fields.
Mappings that extend oracle.toplink.mappings.ForeignReferenceMapping
use foreign keys to find information in the database so that the target object(s) can be instantiated. For example, if every Employee
has an attribute address
that contains an instance of Address
(which has its own descriptor and table) then, the one-to-one mapping for the address
attribute would specify foreign key information to find an Address
for a particular Employee
.
TopLink classifies foreign keys into two categories in mappings–foreign keys and target foreign keys:
In a foreign key, the key is found in the table associated with the mapping's own descriptor. For example, an Employee
foreign key to ADDRESS
would be in the EMPLOYEE
table.
In a target foreign key, the reference is from the target object's table back to the key from the mapping's descriptor's table. For example, the ADDRESS
table would have a foreign key to EMPLOYEE
.
Caution:
Make sure you fully understand the distinction between foreign key and target foreign key before defining a mapping.The table reference is the database table that contains the foreign key references.
Table 28-9 summarizes which relational mappings support this option.
Table 28-9 Relational Mapping Support for Table Reference
Mapping | How to Use Oracle JDeveloper | How to Configure Table and Field References (Foreign and Target Foreign Keys) Using TopLink Workbench |
How to Configure Table and Field References (Foreign and Target Foreign Keys) Using Java |
---|---|---|---|
One-to-one (see Section 27.5, "One-to-One Mapping") |
|
|
|
One-to-many (see Section 27.7, "One-to-Many Mapping") |
|
|
|
Many-to-many (see Section 27.8, "Many-to-Many Mapping") |
|
|
|
Aggregate collection (see Section 27.9, "Aggregate Collection Mapping") |
|
|
|
Direct collection (see Section 27.10, "Direct Collection Mapping") |
|
|
|
Direct map (see Section 27.11, "Direct Map Mapping") |
|
|
|
Using TopLink Workbench, you can either import this table from your database or create it. If you import tables from the database (see Section 5.5.1.3, "Importing Tables from a Database"), TopLink creates references that correspond to existing database constraints (if supported by the driver). You can also define references in TopLink without creating similar constraints on the database.
To specify a table for a mapping reference, use this procedure:
Select the mapped attribute in the Navigator. Its properties appear in the Editor.
Click the Table Reference tab. The Reference tab appears.
Figure 28-5 Table Reference Tab, Table Reference Field
Use the following information to select the field references on the tab:
Field | Description |
---|---|
Table Reference | Select an existing table, or click New to create a new table reference. |
Source and Target Field | Click Add to create new foreign key reference.
To delete an existing key pair reference, select the Source and Target fields and click Remove. |
Source Field | Select the database field from the source table for this foreign key reference. |
Target Field | Select the database field from the target table for this foreign key reference. |
Target Foreign Key | Specify whether or not the reference is from the target object's table back to the key from the mapping's descriptor's table. |
Use the addTargetForeignKeyFieldName
method (and pass the name of the field name of the target foreign key and the source of the primary key in the source table) to specify foreign key information.
For composite source primary keys, use the addTargetForeignKeyFieldName
method for each of the fields that comprise the primary key.
Example 28-3 shows how to use the DescriptorCustomizer
class to add complex join to a mapping.
Example 28-3 Adding Complex Join to a Mapping
public void customize(ClassDescriptor descriptor) {
OneToManyMapping phoneNumbersMapping = new OneToManyMapping();
phoneNumbersMapping =
(OneToManyMapping)descriptor.getMappingForAttributeName("cellPhones");
ExpressionBuilder phone =
phoneNumbersMapping.getSelectionQuery().getExpressionBuilder();
phoneNumbersMapping.addTargetForeignKeyFieldName("PHONE.EMP_ID", "EMP.ID");
phoneNumbersMapping.getSelectionQuery(
phone.getField("PHONE.EMP_ID").equal(phone.getParameter("EMP.ID").
and(phone.getField("PHONE.TYPE').equal("CELL")));
// add mapping to descriptor
descriptor.addMapping(phoneNumbersMapping);
}
Note:
You can provide the same functionality by using a descriptor amendment method (see Section 13.6, "Using the Descriptor Amendment Methods").TopLink supports configuring an inner or outer join at the mapping level for a ForeignReferenceMapping
. When a class that owns the mapping is read, the TopLink runtime will always get the class and the target of the reference mapping with one database hit.
Use this feature only if the target object is always required with the source object, or when indirection (lazy loading) is not used. For more information, see Section 17.2.4, "Indirection (Lazy Loading)".
You can also configure join reading at the query level. For more information, see Section 108.7.1.5, "Join Reading and Object-Level Read Queries".
You can use Oracle JDeveloper, TopLink Workbench, or Java to configure joining at the mapping level.
For more information about joins, see Section 110.2.7, "Expressions for Joining and Complex Relationships".
To use joining in a relationship mapping, use this procedure:
Select the mapped attribute in the Navigator. Its properties appear in the Editor.
Click the General tab. The General tab appears.
Figure 28-6 General Tab, Use Joining Option
To use joining with this relationship, select the appropriate join-fetch method:
Inner
Outer
None (default)
Example 28-4 shows how to use the DescriptorCustomizer
class to add complex join at the mapping level.
Example 28-4 Adding Join at the Mapping Level
public void customize(ClassDescriptor descriptor) {
OneToManyMapping addressMapping = new OneToManyMapping();
addressMapping =
(OneToManyMapping)descriptor.getMappingForAttributeName("address");
addressMapping.useJoining();
...
// add mapping to descriptor
descriptor.addMapping(addressMapping);
}
Note:
You can provide the same functionality by using a descriptor amendment method (see Section 13.6, "Using the Descriptor Amendment Methods").