Oracle Application Server TopLink Mapping Workbench User's Guide 10g (9.0.4) Part Number B10316-01 |
|
Oracle Application Server TopLink uses descriptors to store the information that describes how an instance of a particular class can be represented in a relational database. Most descriptor information can be defined by the OracleAS TopLink Mapping Workbench and read from a project file to be registered with an OracleAS TopLink Mapping Workbench session.
For complete information on the OracleAS TopLink API, refer to the Oracle Application Server TopLink API Reference.
Note: In this document, descriptors refers to OracleAS TopLink descriptors; deployment descriptors refers to EJB deployment descriptors. |
A descriptor stores all the information describing how an instance of a particular class can be represented in a relational database. The OracleAS TopLink Mapping Workbench reads a project .mwp
file to load all a project's information (including descriptor information).
You may need to amend a descriptor (for example, to specify a property not supported by the OracleAS TopLink Mapping Workbench) after reading a project file (see "Amending Descriptors After Loading"). However, do not modify any descriptors after registering them with the session.
OracleAS TopLink descriptors contain the following information:
Any class that registers a descriptor with an OracleAS TopLink Mapping Workbench database session is called a persistent class. OracleAS TopLink does not require that persistent classes provide public accessor methods for any private or protected attributes stored in the database.
See Appendix A, "Object Model Requirements" for more information on persistent classes object model requirements.
OracleAS TopLink descriptors can be a class descriptor, an aggregate descriptor, or an EJB descriptor. After creating a descriptor, use this procedure to change the descriptor type.
You can also select the descriptor and choose Selected > Descriptor Type > specific descriptor type from the menu or by right-clicking on the descriptor in the Navigator pane and selecting Descriptor Type > specific descriptor type from the pop-up menu.
Note:
EJB 2.0 descriptors are created only by reading the |
When changing a descriptor's type, the OracleAS TopLink Mapping Workbench adds or removes property tabs, as needed.
Descriptors define mappings between classes and tables. To display the attributes in a specific class, expand the descriptor item in the Navigator pane (see Figure 1-5).
Use the mapping toolbar (see "Mapping Toolbar") to choose a mapping type for each attribute.
Continue with "Working with Mappings" to modify the mapping.
The OracleAS TopLink Mapping Workbench can automatically map class attributes to a similarly named database field. The 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: You must associate a descriptor with a database table before using the Automap function. See "Setting Descriptor Information" for more information. |
To automap all descriptors in a project, right-click the project icon in the Navigator pane and choose Automap from the pop-up menu or choose Selected > Automap from the menu.
or
To automap a specific descriptor or attribute choose the descriptor/attribute(s). Right-click and select Automap from the pop-up menu or choose Selected > Automap from the menu.
Use this procedure to generate the Java class code for the selected descriptor or package.
Right-click the descriptor or package and choose Export Java Model Source from the pop-up menu. The Choose a Directory dialog box appears.
You can also choose Selected > Export Java Model Source from the menu.
If you have not defined deployment and source code generation defaults (see "Working with Project Options") the OracleAS TopLink Mapping Workbench prompts for a filename and directory.
OracleAS TopLink creates the <DescriptorName>
.java
file in the specified directory.
Each descriptor in the OracleAS TopLink Mapping Workbench contains the following default tabs and specific properties.
Use the Set Advanced Properties function (see "Working with Advanced Properties" and "To Specify the Default Advanced Properties for Descriptors:") to specify additional properties for each descriptor.
Use the Descriptor Info tab to map a descriptor to a specific table in the database, define primary key(s), specify sequencing information, and set caching options.
Field | Description |
---|---|
Associated Table |
Use the drop-down list to select a database table for the descriptor. |
Primary Keys |
Specify the primary key(s) for the table. |
Use Sequencing |
Specify if this descriptor uses sequencing. If selected, specify the Name, Table, and Field for sequencing. See "Working with Sequencing" for more information. |
Read Only |
Specify if this descriptor is read-only. |
Conform Results in Unit of Work |
Specify to use the Refer to the Oracle Application Server TopLink Application Developer's Guide for more information. |
Refreshing Cache |
|
Use the project's default caching options. OracleAS TopLink will not refresh the cache unless a read query is configured to refresh the cache. |
|
Refreshes the objects in the cache on all queries. Note: Using this property may impact performance. |
|
Disables the cache hits on primary key read object queries. |
|
Refreshes the cache only if the object in the database is newer than the object in the cache (as determined by the Optimistic Locking field). See "Working with Optimistic Locking" for more information. |
After generating classes and descriptors, use the Class Info tab to:
To add a new interface to implement, click Add.
To delete an interface, select the interface and click Remove.
To generate source code for the descriptor, click Generate Source Code.
Text description of the illustration clinclas.gif
Use this table to enter data in each field:
To add a new attribute, click Add.
To delete an existing attribute, select the attribute and click Remove.
To rename an existing attribute, select the attribute and click on Rename.
Text description of the illustration clinatt.gif
Select an attribute, then use this table to enter data in each field on the General tab.
Text description of the illustration clinatta.gif
Select an attribute, then use this table to enter data in each field on the Accessors tab.
Field | Description |
---|---|
Get Method |
Choose the |
Set Method |
Choose the |
To generate a get
or set
method for an attribute, click Generate Get/Set Methods.
To add a new method, click Add.
To delete an existing method, select the method and click Remove.
Text description of the illustration clinmeth.gif
Select a method, then use this table to enter data in each field:
Use the Queries tab to specify EJB QL and SQL queries and finders to use for database access. The Queries tab contains two additional tabs: Named Queries and Custom SQL.
For 2.0 CMP projects, the ejb-jar.xml
file stores query lists. You can define the queries in the file and then read them into the OracleAS TopLink Mapping Workbench, or define them on the Queries tab and write them to the file. See "Writing to the ejb-jar.xml File" for more information.
Use this procedure to create custom SQL queries in the OracleAS TopLink Mapping Workbench. For 2.0 CMP projects, the SQL is not written to the ejb-jar.xml
file.
To control the five custom query tabs, you can include your own query object or SQL string for a particular descriptor. The SQL string for each database is defined by the type of database.
For example, the stored procedure to read an object may use the following string:
The query manager requires the following string to read the object:
In this query, the hash character, #
, binds the argument EMP_ID
within the SQL string.
Use named queries to specify SQL, EJB QL, or OracleAS TopLink Expression queries to access the database. EJB QL is a declarative language that presents queries from an object-model perspective. Refer to the EJB specification and the Oracle Application Server TopLink Application Developer's Guide for detailed information.
Field | Description |
---|---|
Expression |
Specify this named query uses an OracleAS TopLink expression. |
SQL |
Specify this named query is a SQL query. |
EJB QL |
Specify this named query is an EJB QL query. |
Query String |
Entry the query. The OracleAS TopLink Mapping Workbench does not validate the query string. Note: For Expressions, double-click the query string or click Edit to create or edit the query string. See "Building Expressions" for more information. |
Field | Description |
---|---|
Refresh Identity Map Results |
Specify the |
Cache Statement |
Specify the
|
Bind Parameters |
Specify the
|
Cache Usage |
Select if/how the query checks the cache before accessing the database. |
In Memory Query Indirection |
Specify how a query reacts when accessing un-instantiated indirection. Use this option to specify the |
Refer to the Oracle Application Server TopLink Application Developer's Guide for additional information on named queries.
Use the Expression Builder to create OracleAS TopLink expressions for Named Queries.
Text description of the illustration expbld.gif
Figure 4-13 calls out the following user-interface components:
Click Remove to remove an existing expression.
Field | Description |
---|---|
First Argument |
Click Edit and select the query key for the first argument. See "Adding Arguments" for more information. |
Operator |
Specify how OracleAS TopLink should evaluate the expression. Valid operators include: Equal, Not Equal, Equal Ignore Case, Greater Than, Greater Than Equal, Less Than, Less Than Equal, Like, Not Like, Like Ignore Case, Is Null, and Not Null. |
Second Argument |
Specify the second argument:
See "Adding Arguments" for more information. |
Each expression contains elements (arguments) to evaluate. Expressions using the Is Null or Not Null operators require only a single argument.
Use this procedure to add new arguments.
Repeat this procedure for each expression or sub-expression.
This expression:
AND 1.manager(Allows Null).lastName EQUAL "Jones" 2.OR 2.1.projects.name LIKE "BETA" 2.2.projects.id EQUAL "4" 3.OR 3.1.AND 3.1.1.address.country EQUAL "Canada" 3.1.2.salary GREATER THAN "25000" 3.2.AND 3.1.1.address.country EQUAL "United States" 3.1.2.salary GREATER THAN "37500"
will find employees who:
The OracleAS TopLink Mapping Workbench uses query keys as an alias for a field name. With an alias, OracleAS TopLink expressions can use the Java names instead of DBMS-specific field names. See "Automatically-generating Query Keys" for additional information.
Use the Query Keys tab to create user-defined queries or to work with automatically generated query keys.
Use the Query keys tab to specify a query key for a descriptor.
To delete an existing query key, select the query key and click Remove.
To rename an existing query key, select the query key and click Rename.
Use the EJB Info tab to display the EJB descriptor's information (from the ejb-jar.xml
file). This tab is available only for EJB descriptors.
You can also specify the following advanced properties for each descriptor:
Right-click a descriptor in the Navigator pane and choose Set Advanced Properties > specific property from the pop-up menu or choose Selected > Set Advanced Properties > specific property from the menu.
See "To Specify the Default Advanced Properties for Descriptors:" for information on specifying default advanced properties.
Some OracleAS TopLink features cannot be configured from the OracleAS TopLink Mapping Workbench. To use these features, you must write a Java method to amend the descriptor after it is loaded as part of the project. This method takes the descriptor as a single parameter. You can then send messages to the descriptor or any of its specific mappings to configure advanced features.
If the After load advanced property is not visible for the descriptor, right-click the descriptor and choose Set Advanced Properties > After Load from pop-up menu or from the Selected menu.
Use the Events tab to specify a methods to execute when certain events occur.
If the Events advanced property is not visible for the descriptor, then right-click the descriptor and choose Set Advanced Properties > Events from pop-up menu or from the Selected menu.
Field | Description |
---|---|
Events Choice |
Select an event for this descriptor. |
Methods |
Select a method for each event. Note: The methods available will vary, depending on the Event. |
See "Supported Events" for a complete list of events and methods.
The OracleAS TopLink Mapping Workbench specifies the default identity mapping for each descriptor in the project options (see "Working with Default Properties"). Use the Identity tab to specify identity map and existence checking information.
Note: Changing the project's default identity policy does not affect descriptors that already exist in the project. |
If the Identity advanced property is not visible for the descriptor, right-click the descriptor and choose Set Advanced Properties > Identity from the pop-up menu or from the Selected menu.
Field | Description |
---|---|
Type |
Use the Type drop-down list to choose the identity map (see Table 4-2 for details). |
Size |
Size of the identity map. |
Existence Checking |
Specify the method of existence checking. |
Use the Inheritance tab to specify the descriptor's inheritance properties as either a root or subclass (branch class or leaf class).
Note: When using an aggregate descriptor in an inheritance, all the descriptors in the inheritance tree must be aggregates. Aggregate and Class descriptors cannot exist in the same inheritance tree. |
Use this procedure to create a root class.
If the Inheritance tab is not visible, right-click the descriptor and choose Set Advanced Properties > Inheritance.
After setting up the root class for inheritance, you must also specify properties for branch and leaf classes.
Use the Locking tab to specify whether the descriptor uses optimistic locking.
If the Locking advanced property is not visible for the descriptor, right-click the descriptor and choose Set Advanced Properties > Locking from the pop-up menu or from the Selected menu.
Use the Interface Alias tab to specify a descriptor's alias. Each descriptor can have one interface alias. Use the interface in queries and relationship mappings.
If the Interface Alias advanced property is not visible for the descriptor, right-click the descriptor and choose Set Advanced Properties > Interface Alias from pop-up menu or from the Selected menu.
A primary key is a column (or a combination of columns) that contains a unique identifier for every record in the table. In the OracleAS TopLink Mapping Workbench, every table that stores persistent objects must have a primary key. Tables that require multiple columns to create an identifier use a composite primary key. Setting the primary key for a table also sets the primary key for the descriptor that uses the table.
The OracleAS TopLink Mapping Workbench implements primary keys using sequence numbers (see "Working with Sequencing").
Each descriptor must provide mappings for its primary key. These mappings may be direct, transformation, or one-to-one. The OracleAS TopLink Mapping Workbench does not require you to define a primary key constraint in the database -- only that the fields specified for the primary key are unique.
Note: Primary keys for classes in an inheritance hierarchy or for descriptors that map to multiple tables have special requirements. Refer to"Working with Inheritance" and "Working with Multiple Tables" for more information. |
Use this procedure to set a primary key for a descriptor.
Sequence numbers are artificial keys that uniquely identify the records in a table. When you define a sequence number field for a descriptor, the OracleAS TopLink Mapping Workbench automatically generates a new sequence number every time you insert a new record into the table.
Use the project's Sequencing tab (see Figure 2-5) or the Sequencing area of a descriptor's Descriptor Info tab (see Figure 4-1) to specify sequencing information
Database tables often use a sequence number as the primary key. The OracleAS TopLink Mapping Workbench can use the database's native support or a sequence table to maintain sequence numbers.
Tip: Oracle recommends using sequence numbers for primary keys because they are single, guaranteed, unique values. |
Other data values may require composite primary keys to make up a unique value, which is less optimal. Additionally, non-artificial values may need to change, and this is not allowed for primary keys.
When implementing sequencing for Entity Beans, you must provide create()
methods and the corresponding ejbCreate()
and ejbPostCreate()
methods for your bean home and bean class.
OracleAS TopLink creates the primary key value when you first insert the bean in the database. The key value is not passed as a parameter to the create()
methods because they do not set the primary key value (the key is generated).
Oracle, Sybase, SQL Server, and Informix databases support native sequencing in which the DBMS generates the sequence numbers. However, the OracleAS TopLink Mapping Workbench must still tell the DBMS to assign sequence number values.
Tip: If you use native sequencing in these databases, the OracleAS TopLink Mapping Workbench cannot support pre-allocation. Oracle recommends using the sequence table instead. Oracle databases support pre-allocation, but only if the sequence increment matches the pre-allocation size. See "Pre-allocating Sequence Numbers" for more information. |
If your database does not use native sequencing, you must manually create the sequence table (named SEQUENCE). Use this table to store each table, as illustrated below:
Field name | Field format | Description |
---|---|---|
SEQ_NAME |
CHAR |
Name of the sequence number |
SEQ_COUNT |
NUMERIC |
Current value |
After creating the table, you must initialize the table within the application. The value of the SEQ_COUNT
field for each sequence should be zero (0), as in the following table.
SEQ_NAME | SEQ_COUNT |
---|---|
EMP_SEQ |
0 |
PROJ_SEQ |
0 |
To increase the speed of database inserts, obtain a block of sequence numbers (by setting an allocation size) instead of executing a corresponding SELECT
statement to obtain the newly assigned sequence number each time you create an object.
OracleAS TopLink uses a default pre-allocation size of 50 when using a sequence table and 1 when using native sequencing.
INCREMENT
is set on the Oracle Sequence object (not the CACHE
option). This increment must match the pre-allocation size specified in the OracleAS TopLink Mapping Workbench. If the increment is set incorrectly, invalid and negative sequence numbers could be generated. The CACHE
option specifies how many sequences are pre-allocated on the database server; the INCREMENT
specifies the number that can be pre-allocated to the database client.
Normally, the database administrator defines the sequence table or sequencing object. However, you can use the OracleAS TopLink schema manager to define the sequence numbers using:
SchemaManager schemaManager = new SchemaManager(session);
schemaManager.createSequences();
You should execute this command only once. The SchemaManager
creates a sequence entry for each registered descriptor.
Refer to the book Oracle Application Server TopLink Application Developer's Guide for more information on using the schema manager to create number information in the database.
Inheritance describes how a child class inherits the characteristics of its parent class. OracleAS TopLink provides multiple methods to preserve the inheritance relationships. You can override mappings that have been specified in a superclass, or map attributes that have not been mapped at all in the superclass.
Note: When using an aggregate descriptor in an inheritance, all the descriptors in the inheritance tree must be aggregates. Aggregate and Class descriptors cannot exist in the same inheritance tree. |
Although inheritance is a standard tool in object-oriented modeling, the current EJB specification contains only general information regarding inheritance. You should fully understand the current EJB specification before implementing inheritance.
Caution: Use caution when employing inheritance. The next EJB specification may dictate inheritance guidelines not supported by the different servers. |
If you are mapping only one class in an inheritance hierarchy, you can map attributes that it inherits from any of its superclasses.
Map inherited attributes to:
You can also do this if you have a common superclass that stores little or no persistent data. For example, if you were mapping subclasses of java.rmi.RemoteObject
, each subclass could be mapped independently.
Store classes with multiple levels of inheritance in a single table to optimize database access speeds.
The following diagram illustrates the Vehicle
object model.
Text description of the illustration javainhr.gif
The entire inheritance hierarchy can share the same table, as in Figure 4-26. The FueledVehicle
and NonFueledVehicle
subclasses can share the same table even though FueledVehicle
has some attributes that NonFueledVehicle
does not. The NonFueledVehicle
instances waste database resources because the database must still allocate space for the unused portion of its row. However, this approach saves on accessing time because there is no need to join to another table to get the additional FueledVehicle
information.
Text description of the illustration inhtable.gif
For subclasses that require additional attributes, use multiple tables instead of a single superclass table to optimize storage space (because there are no unused fields in the database). However, this may affect performance because OracleAS TopLink must read from more than one table before it can instantiate the object. OracleAS TopLink first looks at the class indicator field to determine the class of object to create, then uses the descriptor for that class to read from the subclass tables.
Figure 4-27 illustrates the OracleAS TopLink implementation of the FUELEDVHCL
, CAR
, and BICYCLE
tables. All objects are stored in the VEHICLE
table. The secondary table stores FueledVehicle
, Car
, and Bicycle
information.
Text description of the illustration inhsepar.gif
An inheritance mapping for a root class must be able to locate its subclasses by using one of the following methods:
java.lang.Class
object.
Use a class indicator field in the table of the root class table to indicate which subclass should be instantiated. The indicator field should not have an associated direct mapping unless it is set to read-only.
Note: If the indicator field is part of the primary key, define a write-only transformation mapping for the indicator field. Refer to "Working with Transformation Mappings" for more information. |
You can use strings or numbers as values in the class indicator field. The root class descriptor must specify how the value in the class indicator field translates into the class to be instantiated. The following table illustrates the class indicator mapping from the Vehicle
class containing four entries.
Key | Value |
---|---|
F |
FueledVehicle |
N |
NonFueledVehicle |
C |
Car |
B |
Bicycle |
When working with hierarchies more than two levels deep, the class indicator field and the class indicator mapping can be in only the root class.
OracleAS TopLink allows three types of classes in an inheritance hierarchy:
Vehicle
class in Example 4-25, "Supporting Inheritance Using One Table" is a root class.
FueledVehicle
class in Example 4-25, "Supporting Inheritance Using One Table" is a branch class.
Car
class in Example 4-25, "Supporting Inheritance Using One Table" is a leaf class.
OracleAS TopLink assumes that all of the classes in an inheritance hierarchy have the same primary key, as set in the root descriptor. Child descriptors associated with tables that have different primary keys must define the mapping between the root primary key and the local one.
See "Specifying Multi-table Info" for more information on primary keys in an inheritance hierarchy.
If you are defining the descriptor for a class that inherits attributes from another class, then you can create mappings for those attributes. If you remap an attribute that was already mapped in the superclass, then the new mapping applies to the subclass only. Any other subclasses that inherit the attribute are unaffected.
The mappings list now includes all the attributes from the superclass of this class.
If you leave inherited attributes unmapped, OracleAS TopLink uses the mapping (if any) from the superclass if the superclass's descriptor has been designated as the parent descriptor.
An interface is a collection of method declarations and constants used by one or more classes of objects. Domain classes can implement interfaces or can reference existing interfaces. OracleAS TopLink supports interfaces in the following methods:
An interface descriptor is a descriptor whose reference class is an interface. Each domain class specified in OracleAS TopLink has a related descriptor. A descriptor is a set of mappings that describes how an object's data is represented in a relational database. It contains mappings from the class instance variable to the table's fields, as well as the transformation routines necessary for storing and retrieving attributes. The descriptor acts as the link between the Java object and its database representation.
An interface is a collection of abstract behavior that other classes can use. It is a purely Java object concept and has no representation on the relational database. Therefore, a descriptor defined for the interfaces does not map any relational entities on the database.
Here are the components defined in the interface descriptor:
An interface descriptor does not define any mappings, because there is no concrete data or table associated with it. A list of abstract query keys is defined so that you can issue queries on the interfaces. A read query on the interface results in reading one or more of its implementors.
The following illustration shows an interface implemented by two descriptors.
Text description of the illustration impintr.gif
Following is the sample code implementation for the descriptors for Email
and Phone
:
Descriptor descriptor = new Descriptor(); descriptor.setJavaInterface(Contact.class); descriptor.addAbstractQueryKey("id"); return descriptor; Descriptor descriptor = new Descriptor(); descriptor.setJavaClass(Email.class); descriptor.addDirectQueryKey("id", "E_ID"); descriptor.getInterfacePolicy().addParentInterface(Contact.class); descriptor.setTableName("INT_EML"); descriptor.setPrimaryKeyFieldName("E_ID"); descriptor.setSequenceNumberName("SEQ"); descriptor.setSequenceNumberFieldName("E_ID"); descriptor.addDirectMapping("emailID", "E_ID"); descriptor.addDirectMapping("address", "ADDR"); return descriptor; Descriptor descriptor = new Descriptor(); descriptor.setJavaClass(Phone.class); descriptor.getInterfacePolicy().addParentInterface(Contact.class); descriptor.addDirectQueryKey("id", "P_ID"); descriptor.setTableName("INT_PHN"); descriptor.setPrimaryKeyFieldName("P_ID"); descriptor.setSequenceNumberName("SEQ"); descriptor.setSequenceNumberFieldName("P_ID"); descriptor.addDirectMapping("phoneID", "P_ID"); descriptor.addDirectMapping("number", "P_NUM"); return descriptor;
If the Contact
interface extended another interface, you would call the following method to set its parent:
descriptor.getInterfacePolicy().addParentInterface(Interface.class);
Use single implementor interfaces for applications where only the domain objects' interface is visible. Each domain class has its own unique interface, and no other domain class implements it. The references to other domain objects are also through interfaces.
In such applications, defining a descriptor for each interface would be expensive and may be unnecessary. OracleAS TopLink does not force you to define descriptors for such interfaces. The descriptors are defined for the domain classes, and the parent interface is set as usual.
During the initializing of a descriptor, the interface is given the descriptor of its implementor. This process allows queries on both the domain class and its interface. The only restriction is that each interface should have a unique implementor. In other words, a descriptor is not needed for an interface unless it has multiple implementors.
One-to-one mappings that reference interfaces that have multiple implementors are known as variable one-to-one mappings. See Chapter 6, "Understanding Relationship Mappings", and Chapter 4, "Understanding Descriptors" for more information.
Use this procedure to implement an interface.
The Common Query Keys area displays all the query keys for the interface's implementors.
Descriptors can use multiple tables in mappings. Use multiple tables when:
When a descriptor has multiple tables, you must be able to join a row from the primary table to all the additional tables. By default, OracleAS TopLink assumes that the primary key of the first, or primary, table is included in the additional tables, thereby joining the tables.
OracleAS TopLink also supports custom methods for joining tables.
Use the Multi-table Info tab to define multiple tables for a descriptor in the OracleAS TopLink Mapping Workbench.
If the Multi-table Info advanced property is not visible for the descriptor, right-click the descriptor and choose Set Advanced Properties > Multi-table Info from pop-up menu or from the Selected menu.
When associating an additional table via Primary Key, additional options appear on the Multi-table Info tab. Continue with "Primary Keys Match" or "Primary Keys are Named Differently" to assign the primary key.
Text description of the illustration multipk.gif
When associating a table via Foreign Key, additional options (shown in Figure 4-31) appear. You must choose a reference that relates the correct fields in the primary table to the primary keys in the selected table. Continue with "Tables are Related by Foreign Key in Primary Table" to assign the foreign key.
Text description of the illustration multifk.gif
When associating a descriptor with multiple tables in which the primary key field names are identical, you do not have to specify any additional information. Select the tables from the list of available tables on the Multi-table Info tab. The OracleAS TopLink Mapping Workbench automatically selects the Primary Keys Have the Same Names option.
If the primary keys of the additional table(s) are the same, but they are named differently, you must specify how they relate to the primary key(s) of the default/primary table.
If the primary keys of the additional table are not the same as the primary keys of the primary table, but are instead related to a different set of fields, you must set up a foreign key relation between the tables.
The OracleAS TopLink unit of work feature must be able to clone persistent objects. OracleAS TopLink supports two ways of copying objects:
clone
.
Use the Copying tab to specify how OracleAS TopLink copies objects. OracleAS TopLink supports the following methods:
If the Copying advanced property is not visible for the descriptor, right-click the descriptor and choose Set Advanced Properties > Copying from the pop-up menu or from the Selected menu.
OracleAS TopLink supports several ways to instantiate objects:
You can use custom Java code to override the instantiation policy. Refer to the book Oracle Application Server TopLink Application Developer's Guide for details.
Use the Instantiation tab to specify if objects are instantiated by the default constructor, a specific method, or a factory.
If the Instantiation advanced property is not visible for the descriptor, right-click the descriptor and choose Set Advanced Properties > Instantiation from the pop-up menu or from the Selected menu.
Field | Description |
---|---|
Use Default Constructor |
The default constructor of the class instantiates a new instance. |
Use Method |
Specify a Method to execute to create objects from the database. |
Name of a method to be executed to create objects from the database. The method must be a public, static method on the descriptor's class and must return a new instance of the object. |
|
Use Factory |
Refer to the book Oracle Application Server TopLink Application Developer's Guide for more information. |
The class of the factory object that creates the new instances. |
|
The message to be sent to obtain a factory object. Choose |
|
The method to be sent to the factory object to obtain a new instance that will be populated with data from the database. |
OracleAS TopLink allows you to use wrappers (or proxies) in cases where the persistent class is not the same class that is to be presented to users.
For example, in the Enterprise JavaBeans specification, the Entity bean class (the class that implements javax.ejb.EntityBean
) is persistent but is hidden from users who interact with a class that implements javax.ejb.EJBObject
(the remote interface class). In this example, the EJBObject
acts as a proxy or wrapper for the EntityBean
.
In cases where such a wrapper is used, OracleAS TopLink continues to make the class specified in the descriptor persistent, but returns the appropriate instance of the wrapper whenever a persistent object is requested.
Use a wrapper policy to tell OracleAS TopLink how to create wrappers for a particular persistent class, and how to obtain the underlying persistent object from a given wrapper instance. If you specify a wrapper policy, OracleAS TopLink uses the policy to wrap and unwrap persistent objects as required:
oracle.toplink.descriptors.WrapperPolicy
.
The Descriptor
class provides methods used in conjunction with the wrapper policy:
setWrapperPolicy(oracle.toplink.descriptors.WrapperPolicy)
can be invoked to provide a wrapper policy for the descriptor.
getWrapperPolicy()
returns the wrapper policy for a descriptor.
Refer to the book, Oracle Application Server TopLink Application Developer's Guide, for detailed information.
When using caching to provide performance benefits, you should also use a locking policy to manage database record modification in multi-user environments. Without a locking policy, it may be possible for users to see data that is no longer valid (sometimes called stale data) stored in the cache.
Databases typically support the following locking policies:
UnitOfWork
and updateAndLockObject()
.
Oracle recommends using optimistic locking to ensure that all users are working with valid data before committing changes. OracleAS TopLink supports multiple locking policies for optimistic locking:
UnitOfWork
to be implemented.
For each of the following version locking policies, you must add a specific database field.
OracleAS TopLink records the version as it reads an object from a table. When the client attempts to write the object, OracleAS TopLink compares the version of the object with the version in the table record.
The two version locking policies have different ways of writing to the database:
VersionLockingPolicy
, the number in the version field increments by one.
TimestampLockingPolicy
, a new timestamp is inserted into the row (this policy can be configured to get the time from the server or locally).
For both policies, the values of the write lock field can be the writable mapping within the object.
If the value is stored in the identity map, then by default an attribute mapping is not required for the version field. If the application does map the field, it must make the mappings read-only to allow OracleAS TopLink to control writing the fields.
The following locking policies, included in OracleAS TopLink, do not require any additional fields:
All these policies compare the current values of certain mapped previous values. When using these policies, a UnitOfWork
must be employed for updating the database. Each policy handles its field comparisons in specific way, as defined by the policy.
AllFieldsLockingPolicy
is updated or deleted, all the fields in that table are compared in the where
clause. If any value in that table has been changed since the object was read, the update or delete fails.
ChangedFieldsLockingPolicy
is updated, only the modified fields are compared. This allows for multiple clients to modify different parts of the same row without failure. Using this policy, a delete compares only on the primary key.
SelectedFieldsLockingPolicy
is updated or deleted, a list of selected fields is compared in the statement. Updating these fields must be done by the application manually or through an event.
Whenever any update fails because optimistic locking has been violated, an OptimisticLockException
is thrown. This should be handled by the application when performing any database modification The application must refresh the object and reapply its changes.
The OracleAS TopLink optimistic locking policies that "Working with Optimistic Locking" describes implement the OptimisticLockingPolicy
interface, referenced throughout the OracleAS TopLink code. You can create more policies by implementing this interface and implementing the methods defined.
Use the Locking tab (see Figure 4-22) to specify locking policies for the OracleAS TopLink Mapping Workbench, or refer to the book Oracle Application Server TopLink Application Developer's Guide for more information.
OracleAS TopLink uses identity maps to cache objects for performance and maintain object identity. The OracleAS TopLink Mapping Workbench provides the following identity map types on the Identity tab (see Figure 4-19):
The default identity map size is 100.
Use the following guidelines when employing an identity map:
SoftCacheWeakIdentityMap or HardCacheWeakIdentityMap
policy.
WeakIdentityMap
policy.
FullIdentityMap
policy.
CacheIdentityMap
policy.
NoIdentityMap
policy.
In a Java application, object identity is preserved if each object in memory is represented by one, and only one, object instance. Multiple retrievals of the same object return references to the same object instance -- not multiple copies of the same object.
Maintaining object identity is extremely important when the application's object model contains circular references between objects. You must ensure that two are referencing each other directly, rather than copies of each other. Object identity is important when multiple parts of the application may be modifying the same object simultaneously.
Turn identity off when object identity is not important (for example, for read-only objects).
Identity maps maintain client-side object caches, which increases application performance by minimizing the number of database reads.
When the cache fills up, OracleAS TopLink cleans up the cache based on the identity map policy.
Use a direct query key as an alias for a field name. Query keys allow OracleAS TopLink expressions to refer to a field using Java attribute names (such as firstName
), rather than DBMS-specific names (such as F_NAME
).
Use query keys to:
OracleAS TopLink automatically defines direct query keys for all direct mappings and has a special query key type for each mapping. Typically, use query keys to access fields that do not have direct mappings, such as the version field used for optimistic locking or the type field used for inheritance.
OracleAS TopLink displays automatically generated queries in the Query Keys tab of the Editor pane (see Figure 4-15). You cannot change these keys.
For example, consider the Employee
class in the OracleAS TopLink tutorial: When you define a direct-to-field mapping from the Employee
class (attribute firstName
) to the EMPLOYEE table (field F_NAME) you get a query key for free -- it is automatically generated.
The following code example illustrates using an automatically generated query key within the OracleAS TopLink expression framework.
Vector employees = session.readAllObjects(Employee.class, new ExpressionBuilder().get("firstName").equal("Bob"));
Interface descriptors are defined only with query keys that are shared among their implementors. In the descriptor for the interface, only the name of the query key is specified.
In each implementor descriptor, the key must be defined, and with appropriate field, from one of the implementor descriptor's tables.
Doing this ensures that a single query key can be used to specify foreign key information from a descriptor that contains a mapping to the interface, even if the field names differ.
Consider an Employee
that contains a contact, of type Contact
. Contact
is an interface with two implementors: Phone
and EmailAddress
. Each class has two attributes. The following figure illustrates the generated keys:
Text description of the illustration atgenkey.gif
Note:
Both classes have an attribute, |
Text description of the illustration conintds.gif
Note:
If either of the implementor classes did not have the |
Now that a descriptor with a commonly shared query key has been defined for Contact
, you can use it as the reference class for a variable one-to-one mapping. For example, you can now create a one-to-one mapping for the contact
attribute of Employee
. When you edit the foreign key field information for the mapping, you must match the Employee
descriptor's tables to query keys from the Contact
interface descriptor.
See "Working with Interfaces" and "Working with Relationship Mappings" for more information.
OracleAS TopLink supports query keys for relationship mappings and automatically defines them for all relationship mappings. You can use these keys to join across a relationship. One-to-one query keys define a joining relationship and are accessed through the get()
method in expressions.
One-to-many and many-to-many query keys define a distinct join across a collection relationship and are accessed through the anyOf()
method in expressions. You can also define relationship query keys manually if mapping
does not exist for the relationship. The relationship defined by the query key is data-level expressions.
The following code example illustrates using a one-to-one query key within the OracleAS TopLink expression framework
ExpressionBuilder employee = new ExpressionBuilder(); Vector employees = session.readAllObjects(Employee.class, employee.get("address").get("city").equal("Ottawa"));
Relationship query keys are not supported directly in the OracleAS TopLink Mapping Workbench. To define a relationship query key, you must specify and write an amendment method. Register query keys by sending the addQueryKey()
message.
The following code example illustrates how to define a one-to-one query key.
// Static amendment method in Address class, addresses do not know their owners in the object-model, however you can still query on their owner if a user-defined query key is defined public static void addToDescriptor(Descriptor descriptor) { OneToOneQueryKey ownerQueryKey = new OneToOneQueryKey(); ownerQueryKey.setName("owner"); ownerQueryKey.setReferenceClass(Employee.class); ExpressionBuilder builder = new ExpressionBuilder(); ownerQueryKey.setJoinCriteria(builder.getField("EMPLOYEE.ADDRESS_ ID").equal(builder.getParameter("ADDRESS.ADDRESS_ID"))); descriptor.addQueryKey(ownerQueryKey); }
Use the event manager to specify specific events to occur whenever OracleAS TopLink performs a read, update, delete, or insert on the database.
Applications can receive descriptor events in the following ways:
DescriptorEventListener
interface
DescriptorEventAdapter
adapter class
Objects that implement the DescriptorEventListener
interface can be registered with the descriptor event manager to be notified when any event occurs for that descriptor.
Alternately, you may wish to use the DescriptorEventAdapter
class if your application does not require all the methods defined in the interface. The DescriptorEventAdapter
implements the DescriptorEventListener
interface and defines an empty method for each method in the interface. To use the adapter, first subclass it, then register your new object with the descriptor event manager.
You can use descriptor events in many ways, including:
Use the descriptor's Event tab (see Figure 4-18) to specify events for a descriptor.
To invoke a method called postBuild()
for an Employee
object, the postBuild()
method must be implemented in the Employee
class. This method must also accept one parameter that is an instance of DescriptorEvent
fully qualified with a package name.
A persistent class can register a public method as an event method. A descriptor calls the event method when a particular database operation occurs.
Event methods:
DescriptorEvent
as a parameter
The following code illustrates an event method definition:
Events the DescriptorEventManager
supports include:
In OracleAS TopLink, use named queries to represent SQL or EJB QL finders to use in database accesses. You can create these finders within the OracleAS TopLink Mapping Workbench.
When you create a finder for an EJB, the OracleAS TopLink Mapping Workbench creates a named query and populates the descriptor alias with information from the ejb-jar.xml
file.
Reserved finders are valid for projects with CMP persistence.
The object-relational paradigm extends traditional relational databases with object-oriented functionality. Oracle, IBM DB2, Informix, and other DBMS databases allow users to store, access, and use complex data in more sophisticated ways.
The object-relational standard is an evolving standard mainly concerned with extending the database data structures and the SQL language (SQL 3).
The new features include:
Coinciding with object-relational changes, most database vendors are also extending their server architectures to support features such as:
This section describes how the object-relational features affect OracleAS TopLink descriptors and mappings. The server architecture changes are discussed in the book Oracle Application Server TopLink Application Developer's Guide.
Object-relational databases introduce several new features that allow more complex data to be stored and accessed. One advantage of object-relational databases is that the differences between the object model and data model can be reduced to the point that the two are almost identical. Although this makes the object-relational mapping process easier, it does not reduce the need for a persistence framework such as OracleAS TopLink. Although the JDBC standard has been improved to take advantage of object-relational features in JDBC 2.0, it still remains a low-level database interface. On top of JDBC, frameworks such as OracleAS TopLink can provide applications with much more sophisticated functionality, including units of work, identity maps, expressions, querying, complex mappings, three-tier and enterprise application support.
OracleAS TopLink provides object-relational support through a new type of descriptor object and several new types of mappings. See Chapter 7, "Understanding Object-Relational Mappings" for more information.
OracleAS TopLink supports any JDBC 2.0 driver that complies with JDBC's 2.0 object-relational extensions. Contact your database and JDBC vendor to determine which object-relational features they support.
The OracleAS TopLink Mapping Workbench does not currently support the object-relational descriptor and mappings. Support will be added to the OracleAS TopLink Mapping Workbench in future releases.
You should be able to import most of the simple object-relational table structures into OracleAS TopLink. In addition, you can define the standard non-object-relational descriptor properties and mappings. You can use amendment methods to add any object-relational mappings and features to the descriptors.
In OracleAS TopLink, mappings define how an object's attributes are represented in the database.
All the mapping classes are derived from the DatabaseMapping
class, as Figure 4-37 illustrates.
Text description of the illustration mapclass.gif
OracleAS TopLink associates each mapping with the attribute whose persistence it describes. To create a mapping in the OracleAS TopLink Mapping Workbench, select the attribute to map from the Navigator pane and then click the appropriate button on the mapping toolbar (see "Mapping Toolbar").
Use the mapping's Editor pane to enter specific information for the mapping. Some mappings require more information that others and have multiple tabs in the Editor pane.
Text description of the illustration 1mmapgen.gif
Mapping properties called out in Figure 4-38:
By default, OracleAS TopLink uses direct access to access public attributes. Alternatively, you can use accessor methods to access object attributes when writing the attributes of the object to the database or reading the attributes of the object from the database. This is known as method access.
The attribute's visibility (public, protected, private, or package visibility) and the supported version of JDK may restrict the type of access that you can use.
Starting with JDK 1.2, the Java Core Reflection API provides a means to suppress default Java language access control checks when using reflection. OracleAS TopLink uses reflection to access the application's persistent objects. This means that if you are using a VM that supports the API, then OracleAS TopLink can access an attribute directly, regardless of its declared visibility.
Note: Private variable access under JDK 1.2 requires you to enable the security setting. Consult the JDK documentation for more information. |
Oracle recommends using direct access whenever possible to improve performance and avoid executing any application-specific behavior while building objects.
Use the General tab of the mapping Editor pane (see Figure 4-38) to set the access type as direct or method-based
To change the default access type used by all new mappings, use the Defaults tab on the project Editor pane. See "Working with Default Properties" for more information.
Note: If you change the access default, existing mappings retain their current access settings, but new mappings will be created with the new default. |
Use the Read Only check-box on the General tab of the mapping Editor pane (see Figure 4-38) to set a mapping to be read only. OracleAS TopLink will not consider attributes associated with read-only mappings during update and delete operations.
Because these operations are not actually performed for the mapping, any processes dependent on these operations (such as custom SQL or descriptor events) are not called for read-only. The attributes are still used for read operations.
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.
Direct mappings include a nullValue
attribute. Use this attribute to convert database null values to application-specific values (if the application does not allow null values). This applies when typed as primitives. The null value must be set to the desired value, not the database value.
Null values translate in two directions: from null values read from the database to the specified value, and from the specified value back to null when writing or querying. You can also use OracleAS TopLink to set global default null values on a per-class basis. For more information, refer to the book Oracle Application Server TopLink Application Developer's Guide.
Click the Use Default Value when Database Field is Null option on the General tab (see Figure 4-38) and the Type and Value drop-down lists to specify the null value.
Select the Maintain Bidirectional Relationship Only option on the General tab of the mapping Editor pane (see Figure 4-38) to maintain a bidirectional relationship for a one-to-one or one-to-many mapping. You can also specify the relationship partner.
When defining mappings in code, OracleAS TopLink assumes all mappings are in the first table specified by the descriptor's setTableName()
or addTableName()
method. If the persistent class stores information in multiple tables, any messages sent that require field names should be implemented to pass fully qualified names (that include the table name). Use the following syntax to fully qualify a field:
someMessage("tablename.fieldname");
Some relationship mapping types (direct collection, one-to-many, and many-to-many) contain a Collection Options tab to allow you to specify collection options.
OracleAS TopLink can populate a collection in ascending or descending order, upon your specification. Query keys are automatically created for and with the same name as all attributes mapped as direct-to-field, type conversion, object type, and serialized object mappings.
Text description of the illustration collects.gif
Use this table to enter data in each field:
For 2.0 CMP projects, the ejb-jar.xml
files stores information on bean-to-bean relationships (mappings) in the <relationship>
element. By updating this information in the ejb-jar.xml
, the OracleAS TopLink Mapping Workbench creates new mappings. You can then update the mapping information (such as reference tables).
If the information does not exist in the ejb-jar.xml
file, you can build the mappings in the OracleAS TopLink Mapping Workbench, then write the information to the file. See "Writing to the ejb-jar.xml File" for more information.
|
![]() Copyright © 1997, 2003 Oracle Corporation. All Rights Reserved. |
|