Skip Headers
Oracle TopLink Developer's Guide
10g Release 3 (10.1.3)
B13593-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

Configuring Query Keys

A query key is a schema-independent alias for a database field name. For example, consider a class Employee with attribute firstName mapped directly to a database field F_NAME in database table EMPLOYEE. Without a query key, when you create a query or expression that involves Employee attribute firstName, you must use the database management system-specific field name F_NAME. This makes it more difficult to build a query and ties the query to the schema. With a query key, you can refer to this field using a schema-independent alias, such as firstName.

Table 28-11 summarizes which descriptors support query keys.

Table 28-11 Descriptor Support for Query Keys

Descriptor Using TopLink Workbench
Using Java

Relational Descriptors

Supported.


Supported.


Object-Relational Descriptors

Unsupported

Supported.


EIS Descriptors

Unsupported
Unsupported

XML Descriptors

Unsupported
Unsupported

Using query keys offers the following advantages:

Query keys are automatically generated for all mapped attributes. The name of the query key is the name of the class attribute specified in your object model.

For information on how to use query keys in queries and expressions, see "Query Keys".

When query keys are generated and how you can add or modify query keys depends on the type of mapping or descriptor involved:

Direct Mappings

TopLink Workbench automatically generates query keys for all direct mappings at the time you create the mapping.

TopLink Workbench provides support for adding or modifying query keys for simple unmapped attributes that could be mapped by a direct mapping: for example, the version field used for optimistic locking or the type field used for inheritance. You cannot modify or remove automatically generated query keys.

Relationship Mappings

TopLink automatically generates query keys for all relationship mappings at run time.

For example, if you have a class Customer with attribute orders mapped in a one-to-many relationship to class PurchaseOrders, then the TopLink runtime will generate a query key named orders for this Customer attribute.

TopLink Workbench does not currently support adding or modifying the query keys for relationship mappings. If you must add or modify such a query key, you must do so in Java code, using a descriptor amendment method.

Interface Descriptors

Interface descriptors (see "Relational Interface Descriptors") define only the query keys that are shared among their implementors. In the descriptor for an interface, only the name of the query key is specified.

TopLink Workbench provides support for choosing the implementors of an interface that share at least one common automatically generated query key (see "Configuring Interface Query Keys").

Using TopLink Workbench

To add query keys to simple unmapped fields and to view the query keys automatically generated for directly mapped attributes, use this procedure:

  1. Select a descriptor in the Navigator. Its properties appear in the Editor.

  2. Click the Query Keys tab in the Editor.

    Figure 28-22 Query Keys Tab

    This illustration shows the Query Keys tab.

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.

Use the Field list to select the field in the table associated with the query key.

Using Java

To manually create a relationship query key, implement a descriptor amendment method (see "Configuring Amendment Methods") that uses one of the following ClassDescriptor methods to register the query keys:

  • addQueryKey–specify a query key using an instance of QueryKey such as DirectQueryKey, DirectCollectionQueryKey, ManyToManyQueryKey, OneToManyQueryKey, or OneToOneQueryKey.

  • addDirectQueryKey–add a query key that maps directly to the given database field.

  • addAbstractQueryKey–add an abstract query key to an interface descriptor. Any implementors of that interface must define the query key defined by this abstract query key.

Examples (UNKNOWN STEP NUMBER) , (UNKNOWN STEP NUMBER) , and (UNKNOWN STEP NUMBER) illustrate how to define a query key in Java code.

Example 28-3 Defining a Query Key

// Add a query key for the foreign key field using the direct method
descriptor.addDirectQueryKey("managerId", "MANAGER_ID");

// The same query key can also be added through the addQueryKey method
DirectQueryKey directQueryKey = new DirectQueryKey();
directQueryKey.setName("managerId");
directQueryKey.setFieldName("MANAGER_ID");
descriptor.addQueryKey(directQueryKey);

/* Add a one-to-one query key for the large project of which the employee is a leader (this assumes only one project) */
OneToOneQueryKey projectQueryKey = new OneToOneQueryKey();
projectQueryKey.setName("managedLargeProject");
projectQueryKey.setReferenceClass(LargeProject.class);
ExpressionBuilder builder = new ExpressionBuilder();
projectQueryKey.setJoinCriteria(builder.getField("PROJECT.LEADER_ID").
    equal(builder.getParameter("EMPLOYEE.EMP_ID")));
descriptor.addQueryKey(projectQueryKey);

Example 28-4 Defining a One-to-Many Query Key

/* Add a one-to-many query key for the projects where the employee manages multiple projects */
OneToManyQueryKey projectsQueryKey = new OneToManyQueryKey();
projectsQueryKey.setName("managedProjects");
projectsQueryKey.setReferenceClass(Project.class);
ExpressionBuilder builder = new ExpressionBuilder();
projectsQueryKey.setJoinCriteria(builder.getField("PROJECT.LEADER_ID").     equal(builder.getParameter("EMPLOYEE.EMP_ID")));
descriptor.addQueryKey(projectsQueryKey);

Example 28-5 Defining a Many-to-Many Query Key

/* Add a many-to-many query key to an employee project that uses a join table*/
ManyToManyQueryKey projectsQueryKey = new ManyToManyQueryKey();
projectsQueryKey.setName("projects");
projectsQueryKey.setReferenceClass(Project.class);
ExpressionBuilder builder = new ExpressionBuilder();
projectsQueryKey.setJoinCriteria(builder.getTable("EMP_PROJ").getField("EMP_ID").equal(builder.getParameter("EMPLOYEE.EMP_ID").and(builder.getTable("EMP_PROJ").getField("PROJ_ID").equal(builder.getField("PROJECT.PROJ_ID")));
descriptor.addQueryKey(projectsQueryKey);

Example 28-6 illustrates how to implement a Descriptor amendment method to define a one-to-one query key. In this example, the object model for the Address class does not include a reference to its owner, an Employee object. You can amend the Address class descriptor to add a query key named owner to make up for this deficiency. At run time, you can compose expressions that select Address objects based on this owner query key.

Example 28-6 Defining a One-to-One Query Key with an Amendment Method

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