Skip Headers

Oracle Application Server TopLink Mapping Workbench User's Guide
10g (9.0.4)

Part Number B10316-01
Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Go to previous page Go to next page

4
Understanding Descriptors

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.


Working with 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:

Understanding Persistent Classes

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.

Specifying Descriptor Types

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.


Note:

An EJB descriptor cannot be an aggregate.


To specify a descriptor's type:
  1. Select the descriptor in the Navigator pane.

  2. Click the appropriate descriptor icon (Class Text description of cldesbtn.gif follows.

    Text description of the illustration cldesbtn.gif

    , Aggregate  Text description of agdesbtn.gif follows.

    Text description of the illustration agdesbtn.gif

    , or EJB Text description of ejbbtn.gif follows.

    Text description of the illustration ejbbtn.gif

     ) on the mapping toolbar.

    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 ejb-jar.xml file. See "Mapping EJB 2.0 Entities" for more information.


When changing a descriptor's type, the OracleAS TopLink Mapping Workbench adds or removes property tabs, as needed.

Mapping Descriptors

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.

To map a descriptor:
  1. Select a descriptor in the Navigator pane. Its properties appear in the Editor pane.

  2. On the Descriptor Info tab, associate the descriptor with a database table (see "Setting Descriptor Information").

  3. In the Navigator pane, expand the descriptor to display its attributes.

  4. Select an attribute and click the appropriate mapping button on the Mapping toolbar (see "Mapping Toolbar").

Continue with "Working with Mappings" to modify the mapping.

Automapping Descriptors

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 attributes:

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.

Generating Java Code for Descriptors

Use this procedure to generate the Java class code for the selected descriptor or package.

To generate Java code:

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.

Working with Descriptor Properties

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.

Setting Descriptor Information

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.

To map a descriptor to a table:
  1. Select a descriptor in the Navigator pane. Its properties appear in the Editor pane.

  2. Click the Descriptor Info tab.

    Figure 4-1 Descriptor Info Tab

    Text description of desinfo.gif follows.

    Text description of the illustration desinfo.gif

  3. Use this table to enter data in each field:

    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 conformResultsInUnitOfWork() method for any read object or read all query.

    Refer to the Oracle Application Server TopLink Application Developer's Guide for more information.

    Refreshing Cache

      Default

    Use the project's default caching options. OracleAS TopLink will not refresh the cache unless a read query is configured to refresh the cache.

      Always Refresh

    Refreshes the objects in the cache on all queries.

    Note: Using this property may impact performance.

      Disable Cache Hits

    Disables the cache hits on primary key read object queries.

      Only Refresh if Newer

    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.


    Note:

    Use the caching options to specify how descriptors refresh the objects in the cache during queries. This ensures that queries against the session will refresh the objects from the row data.


Setting Class Information

After generating classes and descriptors, use the Class Info tab to:

To specify class info:
  1. Select a descriptor in the Navigator pane. Its properties appear in the Editor pane.

  2. Click the Class Info tab in the Editor pane.

  3. Select the appropriate tab:

Class Tab

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.

Figure 4-2 Class Tab

Text description of clinclas.gif follows.

Text description of the illustration clinclas.gif

Use this table to enter data in each field:

Field Description

Name

Name of the class. This field is for display only.

Superclass

Click Browse and select a class and package.

Modifiers

    Access Modifiers

Specify if the class is accessible publicly or only within its own package. Non-public classes are not accessible to the OracleAS TopLink Mapping Workbench.

    Other Modifiers

Specify if the class is Final and/or Abstract. Final classes are not included in the superclass selection lists for other classes to extend.

Interfaces Implemented

To add an interface, click Add and select the interface and package. To remove an interface, select the interface and click Remove.

Note: You must save your project after removing an interface

Attributes Tab

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.

Figure 4-3 Attributes - General Tab

Text description of clinatt.gif follows.

Text description of the illustration clinatt.gif

Select an attribute, then use this table to enter data in each field on the General tab.

Field Description

Modifiers

    Access Modifiers

Specify how the attribute is accessible:

    Other Modifiers

Specify whether the attribute is Final, Static, Transient, or Volatile.

Note: Selecting some modifiers may disable others.

Type Information

    Type

Click Browse and select a class and package for the attribute.

    Type Dimensionality

Specify the length of an array. This field applies only if Type is an array.

Figure 4-4 Attributes - Accessors Tab

Text description of clinatta.gif follows.

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 get( ) method for the attribute.

Set Method

Choose the set( ) method for the attribute.

To generate a get or set method for an attribute, click Generate Get/Set Methods.

Methods Tab

To add a new method, click Add.

To delete an existing method, select the method and click Remove.

Figure 4-5 Methods Tab

Text description of clinmeth.gif follows.

Text description of the illustration clinmeth.gif

Select a method, then use this table to enter data in each field:

Field Description

Modifiers

    Access Modifiers

Specify how the attribute is accessible:

    Other Modifiers

Specify whether the attribute is Final, Static, Transient, or Volatile.

Note: Selecting some modifiers may disable others.

Return Type

Click Browse and select a class and package.

Type Dimensionality

Specify the length of the array (Return Type).

Parameters

Click Add to include parameter(s) for the method.

Note: The parameters are loaded in the order listed.

Specifying Queries and Named Finders

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.

To create queries:
  1. In the Navigator pane, select a descriptor.

  2. Click the Queries tab in the Editor pane.

  3. Select the appropriate tab:

Custom SQL Queries

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 create custom SQL queries:
  1. In the Navigator pane, select a descriptor.

  2. Click the Queries tab in the Editor pane.

  3. Click the Custom SQL tab.

    Figure 4-6 Queries Custom SQL Tab

    Text description of qrsqltab.gif follows.

    Text description of the illustration qrsqltab.gif

  4. Click the appropriate SQL function tab and type your own query object or SQL string to control these actions for a descriptor.

    Tab Description

    Insert

    Generates the insertObject() method of the Session class.

    Update

    Generates the updateObject() method of the Session class.

    When customizing a descriptor's update string if the application uses optimistic locking, you must ensure that the row is not written if the version field has changed since the object was read. Also, the update string must increment the version field if the row is written. In addition, the update string must maintain the row count of the database.

    Delete

    Generates the deleteObject() method of the Session class.

    Read

    Generates the readObject() method of the Session class

    Customizing a descriptor's read-object query works only for the version of the readObject() that takes a primary key expression as a parameter. If other expressions are used, OracleAS TopLink generates dynamic SQL. You can define additional named queries for other read-object queries.

    Read All

    Generates the readAllObjects() method of the Session class.

    Customizing a descriptor's read-all query works only for the version of the readAll() that takes the class as a parameter--not the version that takes the class and an expression. As a result, the query reads every single instance. You can define additional named queries for other read-all queries.


    Note:

    The OracleAS TopLink Mapping Workbench does not validate the SQL code that you enter. The code is defined by the specific database type.


Example 4-1 Custom Queries

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.

Named Queries

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.

To create a named query:
  1. In the Navigator pane, select a descriptor.

  2. Click the Queries tab in the Editor pane.

  3. Click the Named Queries tab in the Queries tab. The Named Queries tab contains the following additional tabs:

  4. Click Add to create a new named query. The Add Named Query dialog box appears.

    Figure 4-8 Add named Query

    Text description of addnmdqr.gif follows.

    Text description of the illustration addnmdqr.gif

  5. Select the query type (for EJB descriptors), enter the query name, and press Enter. The OracleAS TopLink Mapping Workbench adds the query to the Named Query tab.


    Note:

    For OracleAS TopLink Reserved Finders, use the drop-down box to select a reserved name. OracleAS TopLink will generate the query at runtime.


  6. Click on the General tab to specify the query type and parameters.

    Figure 4-9 Named Queries General Tab

    Text description of qrnmdgen.gif follows.

    Text description of the illustration qrnmdgen.gif

  7. Use this table to enter data in each field on the General tab.

    Field Description

    Descriptor Alias

    Alias for the descriptor class. This field applies for EJB finders only.

    Name

    Name of the query. The prefix of the query name specifies the query type:

    • find - EJB 2.0

    • ejbSelect - EJB Select

    You cannot change the name of OracleAS TopLink Reserved Finders.

    Type

    Use the drop-down list to specify whether this is a ReadObject or ReadAll query.

    Parameters

    Click Add to add a parameter of a specific type to this query.

    Note: You cannot add parameters for EJB descriptors.

  8. Click on the Format tab to specify the named query and its format.

    Figure 4-10 Named Queries Format Tab

    Text description of qrnmdfor.gif follows.

    Text description of the illustration qrnmdfor.gif

  9. Use this table to enter data in each field on the Format tab.

    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.

  10. Click on the Options tab to specify additional options for the named query.

    Figure 4-11 Named Queries Options Tab

    Text description of qrnmdopt.gif follows.

    Text description of the illustration qrnmdopt.gif

  11. Use this table to enter data in each field on the Options:

    Field Description

    Refresh Identity Map Results

    Specify the refreshIdentityMapResults() method to refresh the attributes of the object resulting from the query.

    Cache Statement

    Specify the cacheStatement() method for the query.

    Bind Parameters

    Specify the bindAllParameters() method for the query.

    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 InMemoryQueryIndirectionPolicy policy.


    Note:

    These options are not available for findOneByQuery and findManyByQuery.


  12. Click Advanced to specify additional named query options.

    Figure 4-12 Advanced Query Options

    Text description of advqropt.gif follows.

    Text description of the illustration advqropt.gif

  13. Use this table to enter data in each field and click OK:

    Field Description

    Maintain Cache

    Specify maintainCache() for the named query.

    Use Wrapper Policy

    Specify the setWrapperPolicy() for the named query.

    Prepare SQL Once

    Specify the setShouldPrepare() for the named query. By default, OracleAS TopLink optimizes queries to generate their SQL only once. You may need to disable this option for certain types of queries that require dynamic SQL based on their arguments, such as:

    • Expressions that use equal where the argument value could be null. This may cause problems on databases that require IS NULL, instead of = NULL.

    • Expressions that use in and use parameter binding. This will cause problems as the in values must be bound individually.

    Cache Query Results

    Specify the cacheQueryResults() for the query. OracleAS TopLink can maintains an internal cache of the objects previously returned by a read query.

    Refresh Remote Identity Map Results

    Specify the refreshRemoteIdentityMapResult() method for the query. OracleAS TopLink can refresh the attributes of the object(s) resulting from the query. With cascading, OracleAS TopLink will also refresh the private parts of the object(s).

    Pessimistic Locking

    Specify the pessimistic locking policy for the query.

    Distinct State

    Specify if OracleAS TopLink prints the DISTINCT clause, if a distinct has been set.

    Query Timeout

    Specify if the query will time out (or abort) after a specified number of seconds.

    Maximum Rows

    Specify if the query will limit the results to a specified number of rows. Use this to option for queries that could return an excessive number of objects.

Refer to the Oracle Application Server TopLink Application Developer's Guide for additional information on named queries.

Building Expressions

Use the Expression Builder to create OracleAS TopLink expressions for Named Queries.

To build an expression:
  1. From the Named Queries Format tab (see Figure 4-10), click Edit (or double-click a query string). The Expression Builder dialog box appears.

    Figure 4-13 Expression Builder

    Text description of expbld.gif follows.

    Text description of the illustration expbld.gif

    Figure 4-13 calls out the following user-interface components:

    1. Expression tree

    2. Arguments

  2. Click Add or Add Nested to create a new expression. OracleAS TopLink assigns a sequence number to each node and nested node.

    Click Remove to remove an existing expression.

  3. Select the node and use the Logical Operator drop-down list to specify the operator for the node (AND, OR, Not AND, or Not OR).

  4. Choose the expression and use this table to enter data in each field:

    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:

    • Literal -- Click Edit and choose a literal type and value.

    • Query Key -- Click Edit and select the query key.

    • Parameter -- Choose a previously created parameter argument.

    See "Adding Arguments" for more information.

  5. Click OK. The OracleAS TopLink Mapping Workbench adds the expression to Named Queries tab.

Adding Arguments

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.

  1. Select an existing expression or click Add (or Add Nested) to add a new expression to the named query.

  2. For the First Argument, click Edit. The Choose Query Key dialog box appears.

    Figure 4-14 Choose Query Key

    Text description of choseqk.gif follows.

    Text description of the illustration choseqk.gif

  3. Select the attribute, specify if the query allows a null value, and click OK.

  4. Use the Operator drop-down list to specify how OracleAS TopLink should evaluate the expression.

  5. For the Second Argument, select Literal, Query Key, or Parameter, and click Edit.

    • For Literal arguments, the Edit the Literal Type and Value dialog box appears. Choose the literal type (such as String or Integer) and value.

    • For Query Key arguments, the Choose Query Key dialog box appears (see Figure 4-14).

    • For Parameter arguments, use the drop-down list to select the specific parameter, as created on the Named Queries General tab (see Figure 4-9).

Repeat this procedure for each expression or sub-expression.

Example 4-2 Sample 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:

Query Keys

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.

Specifying Query Keys

Use the Query keys tab to specify a query key for a descriptor.

To specify query keys:
  1. Select a descriptor in the Navigator pane. Its properties appear in the Editor pane.

  2. Click the Query Keys tab in the Editor pane.

    Figure 4-15 Query Keys Tab

    Text description of querykey.gif follows.

    Text description of the illustration querykey.gif

  3. To add a new query key, click Add.

    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.

  4. Use the Field drop-down list to select the field in the table used by the query.

Displaying EJB descriptor Information

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.

To display EJB descriptor information:
  1. In the Navigator pane, select an EJB descriptor.

  2. Click the EJB Info tab in the Editor pane.

    Figure 4-16 EJB Info Tab

    Text description of ejbinfo.gif follows.

    Text description of the illustration ejbinfo.gif

  3. Use this table to identify each field:

    Field Description

    EJB Name

    Base name. When using EJB 2.0, this is specified in the <ejb-name> element of the ejb-jar.xml file.

    Primary Key Class

    Primary key. When using EJB 2.0, this is specified in the <prim-key-class> element of the ejb-jar.xml file.

    Local Interface

    Local interface. When using EJB 2.0, this is specified in the <local> element of the ejb-jar.xml file.

    Local Home Interface

    Local home interface. When using EJB 2.0, this is specified in the <local-home> element of the ejb-jar.xml file.

    Remote Interface

    Remote interface. When using EJB 2.0, this is specified in the <remote> element of the ejb-jar.xml file.

    Remote Home Interface

    Remote interface. When using EJB 2.0, this is specified in the <home> element of the ejb-jar.xml file.


    Note:

    When using EJB 2.0 persistence, these fields are for display only.


Working with Advanced Properties

You can also specify the following advanced properties for each descriptor:

To display advanced properties:

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.

Amending Descriptors After Loading

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.

To a specify a method to execute after loading the descriptor:
  1. Select a descriptor in the Navigator pane. Its properties appear in the Editor pane.

    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.

  2. Click the After load tab in the Editor pane.

    Figure 4-17 After Load Tab

    Text description of aftrload.gif follows.

    Text description of the illustration aftrload.gif

  3. Use this table to enter data in each field:

    Field Description

    After Loading

    Specify whether the OracleAS TopLink Mapping Workbench should execute a method after loading the descriptor.

    Class

    Click Browse and choose the class of the method to execute.

    Static Method

    Use the Static Method drop-down list to choose the method to execute.

Specifying Events

Use the Events tab to specify a methods to execute when certain events occur.

To specify an event method:
  1. Select a descriptor in the Navigator pane. Its properties appear in the Editor pane.

    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.

  2. Click the Event tab in the Editor pane.

    Figure 4-18 Events Tab

    Text description of events.gif follows.

    Text description of the illustration events.gif

  3. Use this table to enter data in each field:

    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.

Specifying Identity Mapping

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.


To specify an identity map for a descriptor:
  1. In the Navigator pane, select a descriptor.

    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.

  2. Click the Identity tab.

    Figure 4-19 Identity Tab

    Text description of identity.gif follows.

    Text description of the illustration identity.gif

  3. Use this table to enter data in each field:

    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.

Specifying Inheritance

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.


Creating a Root Class

Use this procedure to create a root class.

To specify a root class:
  1. In the Navigator pane, select the descriptor you wish to specify as the root.

  2. Choose the Inheritance tab in the Property pane.

    If the Inheritance tab is not visible, right-click the descriptor and choose Set Advanced Properties > Inheritance.

    Figure 4-20 Creating a Root Class

    Text description of inhroot.gif follows.

    Text description of the illustration inhroot.gif

  3. To instantiate the descriptor's subclasses when queried, select the Read Subclasses on Query checkbox. Select a database view to use for reading subclasses if desired.


    Note:

    The view can be used for root or branch classes that have subclasses spanning multiple tables. The view must apply an outer-join or union all to the subclass tables.


  4. Select the Is Root Descriptor checkbox.

  5. You can use a class extraction method or a class indicator field to specify which class to instantiate on querying. Choose the option and select the appropriate method or field.

  6. If you use a class indicator field, you can use the class name as the indicator, or you can use a class indicator dictionary. Choose which option you wish to use and specify the necessary information.

  7. If you use an indicator dictionary, choose the indicator type and set the indicator values for each subclass.


    Note:

    A list of subclasses and their indicator values appears when the subclasses have set their parent descriptor. Abstract roots are not in the list.


  8. If you want instances of the subclasses to be instantiated when the root class is queried, select the Read Subclasses on Query checkbox. Do not select this checkbox for leaf classes.

Creating Branch and Leaf Classes

After setting up the root class for inheritance, you must also specify properties for branch and leaf classes.

To create branch and leaf classes:
  1. In the Navigator pane, select the descriptor for which to specify inheritance information.

  2. If the Inheritance advanced property has not been added to the descriptor, right-click the descriptor and choose Set Advanced Properties > Inheritance.

  3. Click the Inheritance tab of the Editor pane.

  4. Ensure that Is Root Descriptor is not selected. The Parent Descriptor drop-down list is now enabled and the class indicator information is disabled.

    Figure 4-21 Creating Branch and Leaf Classes

    Text description of inhbr_lf.gif follows.

    Text description of the illustration inhbr_lf.gif

  5. Choose the parent descriptor from the Parent Descriptor drop-down list. This may be the root class or a branch class.

  6. Select the Read Subclasses on Query option if this is a branch class and you want its subclasses to be instantiated when it is queried. Choose a database view for reading subclasses, if desired. Do not select this checkbox for leaf classes.

Specifying Optimistic Locking

Use the Locking tab to specify whether the descriptor uses optimistic locking.

To specify a descriptor's locking policy:
  1. In the Navigator pane, select a descriptor.

    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.

  2. Click the Locking tab.

    Figure 4-22 Locking Tab

    Text description of locking.gif follows.

    Text description of the illustration locking.gif

  3. Use this table to enter data in each field:

    Field Description

    Optimistic Locking

    Specify that the descriptor uses optimistic locking.

    Database Field

    Select the correct database field used for optimistic locking.

    Version Locking

    Specify that the descriptor uses version locking.

    Timestamp Locking

    Specify that the descriptor uses timestamp locking.

    Store Version in Cache

    Specify whether you want to store the version information in the cache.

Specifying an Interface Alias

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.


Note:

If you use an interface alias, do not associate an interface descriptor with the interface.


To specify an interface alias:
  1. In the Navigator pane, select a descriptor.

    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.

  2. Click the Interface Alias tab.

    Figure 4-23 Interface Alias Tab

    Text description of intralis.gif follows.

    Text description of the illustration intralis.gif

  3. Click Browse and select an interface.

Working with Primary Keys

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.


Setting a Primary Key for Descriptors

Use this procedure to set a primary key for a descriptor.

To set a primary key:
  1. Select a descriptor in the Navigator pane. Its properties appear in the Editor pane.

  2. Click the Descriptor Info tab.

    Figure 4-24 Primary Keys

    Text description of despk.gif follows.

    Text description of the illustration despk.gif

  3. Select the field(s) to set as the primary key.

Working with Sequencing

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.

Using Sequence Numbers with Entity Beans

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).


Note:

Be careful when using transactions with these create methods. If you create an Entity Bean within a transaction and you use native sequencing in Sybase, SQL Server or Informix, then the bean's key is not initialized until the transaction commits and the bean is persisted to the database for the first time.


Using Native Sequencing

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.

Using Sequence Tables

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

Pre-allocating Sequence Numbers

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.

Creating the Sequence Table on the Database

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.

Working with Inheritance

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.


Using Inheritance with EJBs

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.


Mapping Inherited Attributes in One Descriptor

If you are mapping only one class in an inheritance hierarchy, you can map attributes that it inherits from any of its superclasses.

To map attributes in one descriptor:
  1. In the Navigator pane, select a descriptor.

  2. Right-click the descriptor and choose Map Inherited Attributes > specific location from the pop-up menu. You can also choose Selected > Map Inherited Attributes from the menu.

    Map inherited attributes to:

    • Superclass

    • Root minus one

    • Selected class

  3. Map the now visible attributes as though they belonged to this descriptor.

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.

Supporting Inheritance Using One Table

Store classes with multiple levels of inheritance in a single table to optimize database access speeds.

The following diagram illustrates the Vehicle object model.

Figure 4-25 Supporting Inheritance Using One Table

Text description of javainhr.gif follows.

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.

Figure 4-26 Inheritance Using a Superclass Table with Optional Fields

Text description of inhtable.gif follows.

Text description of the illustration inhtable.gif

Supporting Inheritance Using Multiple Tables

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.

Figure 4-27 Inheritance Using Separate Tables for Each Subclass

Text description of inhsepar.gif follows.

Text description of the illustration inhsepar.gif


Note:

Because NonFueledVehicle does not hold any attributes or relationships, it does not need a secondary table. For performance considerations, this design is inefficient because it requires multiple table fetching.


Finding Subclasses

An inheritance mapping for a root class must be able to locate its subclasses by using one of the following methods:

Providing a Class Indicator Field

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.

Table 4-1 Class Indicator Mapping from the Vehicle Class
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.


Note:

All concrete classes in the hierarchy must have a defined indicator value.


Understanding Root, Branch, and Leaf Classes in an Inheritance Hierarchy

OracleAS TopLink allows three types of classes in an inheritance hierarchy:

Specifying Primary Keys in an Inheritance Hierarchy

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.

Mapping Inherited Attributes in a Subclass

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.

To view and map attributes inherited from a superclass:
  1. In the Navigator pane, right-click a descriptor and choose Map Inherited Attributes > selected class from the pop-up menu or choose Selected > Map Inherited Attributes from the menu.

    The mappings list now includes all the attributes from the superclass of this class.

  2. Map any desired attributes. See "Working with Mappings" for more information.

    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.

Working with Interfaces

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:

Understanding Interface Descriptors

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.


Note:

You cannot create or edit interface descriptors in the OracleAS TopLink Mapping Workbench.


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.

Figure 4-28 Classes Implement an Interface

Text description of impintr.gif follows.

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);

Single Implementor Interfaces

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.

Implementing an Interface

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.

To configure an interface descriptor:
  1. In the Navigator pane, select an interface.

  2. On the Implementors tab in the Editor pane, click the descriptors that implement this interface and share at least one common query key.

    Figure 4-29 Implementors Tab

    Text description of intrprop.gif follows.

    Text description of the illustration intrprop.gif

The Common Query Keys area displays all the query keys for the interface's implementors.

To specify a class descriptor as a single implementor of an interface:
  1. In the Navigator pane, select the descriptor that will be the sole implementor of an interface.

  2. If the Interface Alias advanced descriptor property is not visible for this descriptor, choose Set Advanced Properties > Interface Alias from the Selected menu or the pop-up menu to create the Interface Alias page.

  3. Select the interface that will serve as an alias for this descriptor on the Interface Alias page. It is not necessary for this interface to have a descriptor in the project, and in fact, if an associated descriptor exists, it will be removed. Every instance of the interface will now be treated as an instance of this class as well.

Working with Multiple Tables

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.

Specifying Multi-table Info

Use the Multi-table Info tab to define multiple tables for a descriptor in the OracleAS TopLink Mapping Workbench.

To associate multiple tables with a descriptor:
  1. In the Navigator pane, select a descriptor.

    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.

  2. Click the Multi-table Info tab.

    Figure 4-30 Multi-table Info Tab

    Text description of multiinf.gif follows.

    Text description of the illustration multiinf.gif

  3. Use this table to enter data in each field:

    Field Description

    Primary Table

    The primary table for this descriptor. This field is for display only.

    Additional Tables

    Use the Add and Remove buttons to add or remove additional tables.

    Associated Via

    Specify if each Additional Table is associated by its Primary or Foreign key.

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.

Figure 4-31 Associating Multiple Tables via Primary Key

Text description of multipk.gif follows.

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.

Figure 4-32 Associating Multiple Tables via Foreign Key

Text description of multifk.gif follows.

Text description of the illustration multifk.gif

Primary Keys Match

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.

Primary Keys are Named Differently

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.

  1. Select the associated table, and select Associated Via Primary Key.

  2. Select Primary Keys Have Different Names.

  3. In the Primary Key Reference area (Figure 4-31), choose a table reference that relates how the primary keys of the primary table relate to the primary keys of the selected table. Use the drop-down list to select a primary key association.

Tables are Related by Foreign Key in 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.

  1. Select the associated table, and select Associated Via Foreign Key.

  2. Use the drop-down list to choose a foreign key reference that relates the correct fields in the primary table to the primary keys in the selected table. Click Browse to create a reference.

Working with a Copy Policy

The OracleAS TopLink unit of work feature must be able to clone persistent objects. OracleAS TopLink supports two ways of copying objects:

Setting the Copy Policy

Use the Copying tab to specify how OracleAS TopLink copies objects. OracleAS TopLink supports the following methods:

To specify a copy method:
  1. Select a descriptor in the Navigator pane. Its properties appear in the Editor pane.

    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.

  2. Click the Copying tab in the Editor pane.

    Figure 4-33 Copying Tab

    Text description of copying.gif follows.

    Text description of the illustration copying.gif

  3. Use this table to enter data in each field:

    Field Description

    Use Instantiation Policy

    Creates a new instance of the object using the descriptor's instantiation policy.

    Use Clone Method

    Specifies to call the clone() method of the object.

    Method

    Select the clone method from the drop-list. Click Create New Method to create a new method.

Working with Instantiation Policy

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.

Setting Instantiation Policy

Use the Instantiation tab to specify if objects are instantiated by the default constructor, a specific method, or a factory.

To set the instantiation policy:
  1. In the Navigator pane, select a descriptor.

    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.

  2. Click the Instantiation tab.

    Figure 4-34 Instantiation Tab

    Text description of instant.gif follows.

    Text description of the illustration instant.gif

  3. Use this table to enter data in each field:

    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.

      Method

    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.

      Factory Class

    The class of the factory object that creates the new instances.

      Factory Method

    The message to be sent to obtain a factory object. Choose <nothing> to use the default constructor.

      Instantiation Method

    The method to be sent to the factory object to obtain a new instance that will be populated with data from the database.

Working with a Wrapper Policy

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:

Setting the Wrapper Policy Using Java Code

The Descriptor class provides methods used in conjunction with the wrapper policy:

Refer to the book, Oracle Application Server TopLink Application Developer's Guide, for detailed information.

Working with Optimistic Locking

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:

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:

Using Version Locking Policies

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:

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.

Using Field Locking Policies

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.

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.

Specifying Advanced Optimistic Locking Policies

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.

Working with Identity Maps

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):

Table 4-2 Identity Maps  
Identity Map Description

Full identity map

Provides full caching and guaranteed identity. Caches all objects and does not remove them. This method may be memory intensive when many objects are read.

Do not use on batch type operations.

Soft cache weak identity map

(default with JDK 1.2, available since JDK 1.2)

Similar to the weak identity map except that it maintains a most-frequently-used sub-cache. The size of the sub-cache is proportional to the size of the identity map as specified by descriptor's setIdentityMapSize() method. The sub-cache uses soft references to ensure that these objects are garbage-collected only if the system is low on memory.

Hard cache weak identity map

(available since JDK 1.2)

Identical to the soft cache weak identity map except that it uses hard references in the sub-cache. Use this identity map if soft references do not behave properly on your platform.

Weak identity map (available since JDK 1.2) 

Similar to the full identity map except that the map holds the objects using weak references. This method allows full garbage collection and provides full caching and guaranteed identity.

Cache identity map

Furnishes caching and identity, but does not guarantee identity. A cache identity map maintains a fixed number of objects specified by the application. Objects are removed from the cache on a least-recently-used basis. This method allows object identity for the most commonly used objects.

No identity map

Does not preserve object identity and does not cache objects.

Identity Map Size

The default identity map size is 100.

Design Guidelines

Use the following guidelines when employing an identity map:

Using Object Identity

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).

Caching 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.

Working with Query Keys

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:

Automatically-generating Query Keys

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.

Example 4-3 Automatically Generated Query Key

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"));

Using Query Keys in Interface Descriptors

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:

Figure 4-35 Auto-generated Query Keys for Phone and Email

Text description of atgenkey.gif follows.

Text description of the illustration atgenkey.gif


Note:

Both classes have an attribute, id, that is directly mapped to fields that have different names. However, a query key is generated for this attribute. For the Contact interface descriptor, indicate that the id query key must be defined for each of the implementors, as Figure 4-36 illustrates.


Figure 4-36 Contact interface Descriptor with Common Query Key id

Text description of conintds.gif follows.

Text description of the illustration conintds.gif


Note:

If either of the implementor classes did not have the id query key defined, that descriptor would be flagged as deficient.


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.

Relationship Query Keys

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.

Example 4-4 One-to-one Query Key

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"));

Defining Relationship Query Keys by Amending a Descriptor

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.

Example 4-5 Defining One-to-one Query Key Example

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);
}

Working with Events

Use the event manager to specify specific events to occur whenever OracleAS TopLink performs a read, update, delete, or insert on the database.


Note:

OracleAS TopLink uses the Java event model.


Applications can receive descriptor events in the following ways:

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.

Example 4-6 Event Example

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.

Registering an Event with a Descriptor

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:

Example 4-7 Registering an Event

The following code illustrates an event method definition:

Supported Events

Events the DescriptorEventManager supports include:

Post-X Methods:
 
Updating Methods:
 
Inserting Methods:
 
Writing Methods:
 
Deleting Methods:
 

Working with Finders

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.

Working with Object-relational Descriptors

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.

Effect on OracleAS TopLink

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.

Databases OracleAS TopLink Supports

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.

Defining Object-Relational Descriptors

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.

Working with Mappings

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.

Figure 4-37 Mapping Classes Hierarchy

Text description of mapclass.gif follows.

Text description of the illustration mapclass.gif

Working with Common Mapping Properties

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.

Figure 4-38 Sample Properties for a Mapping

Text description of 1mmapgen.gif follows.

Text description of the illustration 1mmapgen.gif

Mapping properties called out in Figure 4-38:

  1. Specify if read-only.

  2. Specify access method.

Specifying Direct Access and Method Access

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.

Setting the Access Type

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.


Specifying Read-Only Settings

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.


Note:

The primary key mappings must not be read-only.


Mappings defined for the write-lock or class indicator field must be read-only, unless the write-lock is configured not to be stored in the cache and the class indicator is part of the primary key.

Defaulting Null Values

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.


Note:

You must specify the Type and Value in the mapping form.


Maintaining Bidirectional Relationships

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.

Specifying Field Names and Multiple Tables

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");

Specifying Collection Properties

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.

Figure 4-39 Collection Options

Text description of collects.gif follows.

Text description of the illustration collects.gif

Use this table to enter data in each field:

Field Description

Container Policy

    Collection or Map Class

Select the collection or map class to use for this collection mapping.

    Use Default Container Class

If Container Policy = Use Collection Class, select the default Collection Class for the mapping.

    Use Default Map Class

If Container Policy = Use Map Class, select the default Map Class and Key Method for the mapping.

Order Query Results

Specify how the collection results are sorted for queries.

Specifying Mapping information in ejb-jar.xml File

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.


Go to previous page Go to next page
Oracle
Copyright © 1997, 2003 Oracle Corporation.

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