Oracle® TopLink Developer's Guide 10g Release 3 (10.1.3.1.0) Part Number B28218-01 |
|
|
View PDF |
A TopLink project encapsulates both mapping metadata and, where relevant, data source access information. The project is the primary object used by TopLink at run time. Each session (excluding the session broker) in a deployed application references a single project.
This chapter explains the following:
Table 17-1 lists the project types available in TopLink, classifies each as basic or advanced, and indicates how to create each.
Table 17-1 TopLink Project Types
Project Type | Description | Type | TopLink Workbench | Java |
---|---|---|---|---|
|
A project for transactional persistence of Java objects to a relational database or an object-relational database accessed using Java Database Connectivity (JDBC). Supports TopLink queries and expressions. |
Basic |
![]() |
![]() |
|
A project for transactional persistence of Java objects to a nonrelational data source accessed using a J2EE Connector Architecture (J2C) adapter and any supported EIS record type, including indexed, mapped, or XML. Supports TopLink queries and expressions. |
Advanced |
![]() |
![]() |
|
A project for nontransactional, nonpersistent (in-memory) conversion between Java objects and XML schema (XSD)-based documents using Java Architecture for XML Binding (JAXB). Does not support TopLink queries and expressions. |
Advanced |
![]() |
![]() |
For more information, see the following:
This section describes concepts unique to TopLink projects, including the following:
The project type you choose determines the type of descriptors and mappings you can use. There is a project type for each data source type that TopLink supports.
Table 17-2 summarizes the relationship between project, descriptor, and mappings.
TopLink supports both relational and nonrelational projects.
Relational projects persist Java objects to a relational database.
Nonrelational projects persist Java objects to another (nonrelational) type of data source, or perform nonpersistent (see "Persistent and Nonpersistent Projects") data conversion. For example, to persist Java objects to an EIS data source by using a J2C adapter, use an EIS project. To perform nonpersistent (in-memory) conversions between Java objects and XML elements, use an XML project.
TopLink supports projects you use for applications that require persistent storage of Java objects. For example, use a relational project to persist Java objects to a relational database, or an EIS project to persist Java objects to an EIS data source by way of a J2C adapter.
TopLink also supports projects you use for applications that require only nonpersistent (in-memory) data conversion. For example, use an XML project to perform nonpersistent (in-memory) conversion between Java objects and XML elements.
The login (if any) associated with a project determines how the TopLink runtime connects to the project's data source.
A login includes details of data source access, such as authentication, use of connection pools, and use of external transaction controllers. A login owns a platform.
A platform includes options specific to a particular data source, such as binding, use of native SQL, use of batch writing, and sequencing. For more information about platforms, see "Projects and Platforms".
For projects that do not persist to a data source, a login is not required. For projects that do persist to a data source, a login is always required.
In TopLink Workbench, the project type determines the type of login that the project uses, if applicable.
You can use a login in a variety of roles. A login's role determines where and how you create it. The login role you choose depends on the type of project you are creating and how you intend to use the login:
You create a session login in the sessions.xml
file for TopLink applications that do not use container-managed persistence (CMP).
Typically, the TopLink runtime instantiates a project when you load a session from the sessions.xml
file (see Chapter 75, "Acquiring and Using Sessions at Run Time"). The runtime also instantiates a login and its platform based on the information in the sessions.xml
file.
The TopLink runtime uses the information in the session login whenever you perform a persistence operation using the session in your non-CMP TopLink application.
In this case, you do not configure a deployment login (see "CMP Deployment Role: Deployment Login").
If you are using TopLink Workbench and your login is based on a relational database platform, you must also configure a development login (see "Development Role: Development Login").
If a sessions.xml
file contains a login, this login overrides any other login definition.
There is a session login type for each project type that persists to a data source. For a complete list of login types available, see "Data Source Login Types".
For information on configuring a session login, see "Configuring a Session Login".
You create a deployment login in the project.xml
file (also known as the toplink-ejb-jar.xml
file) for a TopLink-enabled CMP application.
When you deploy your TopLink-enabled CMP application with its toplink-ejb-jar.xml
file, the application server or EJB container uses the information in the deployment login whenever your business logic performs a persistence operation from within an entity bean with container-managed persistence.
In this case, you do not configure a session login (see "Non-CMP Session Role: Session Login"). In fact, there is no session.xml
file at all (see "CMP Applications and Session Metadata").
If you are using TopLink Workbench and your login is based on a relational database platform, you must also configure a development login (see "Development Role: Development Login").
For information on creating a deployment login, see "Configuring Development and Deployment Logins".
Using TopLink Workbench, you create a development login in the TopLink Workbench project file when your project is based on a relational database platform.
TopLink Workbench uses the information in the development login whenever you perform a data source operation from within TopLink Workbench, for example, whenever you read or write schema information from or to a data store during application development. The development login information is never written to a sessions.xml
or project.xml
file.
The development login is never used when you deploy your application: it is overridden by either the sessions.xml
file (see "Non-CMP Session Role: Session Login") or the project.xml
file (see "CMP Deployment Role: Deployment Login").
For more information on creating a development login, see "Configuring Development and Deployment Logins".
The platform (if any) associated with a project tells the TopLink runtime what specific type of data source a project uses.
A platform includes options specific to a particular data source, such as binding, use of native SQL, use of batch writing, and sequencing.
A login includes details of data source access, such as authentication, use of connection pools, and use of external transaction controllers. A login owns a platform. For more information about logins, see "Projects and Login".
For projects that do not persist to a data source, a platform is not required. For projects that do persist to a data source, a platform is always required.
In TopLink Workbench, the project type determines the type of platform that the project uses, if applicable.
There is a platform type for each project type that persists to a data source. For a complete list of platform types available, see "Data Source Platform Types".
An essential part of maintaining object identity (see "Cache Type and Object Identity") is sequencing: managing the assignment of unique values to distinguish one instance from another.
Projects have different sequencing requirements, depending on their types:
For relational projects, you typically obtain object identifier values from a separate sequence table (or database object) dedicated to managing object identifier values (see "Understanding Sequencing in Relational Projects").
For EIS projects, you typically use a returning policy (see "Configuring Returning Policy") to obtain object identifier values managed by the EIS data source.
For XML projects, because you are simply performing transformations between objects and XML documents, sequencing is not an issue.
To configure sequencing, you must configure:
How to obtain sequence values (see "Configuring how to Obtain Sequence Values"), and
Where to write sequence values when an instance of a descriptor's reference class is created (see "Configuring Where to Write Sequence Values")
Depending on the type of sequencing you use and the architecture of your application, you may consider using a sequence connection pool. For more information, see "Sequence Connection Pools".
To determine how TopLink obtains sequence values, you configure TopLink sequencing at the project or session level, depending on the type of project you are building:
In a CMP project, you do not configure a session directly: in this case, you must configure sequences at the project level (see "Configuring Sequencing at the Project Level").
In a non-CMP project, you can configure a session directly: in this case, you can use session-level sequence configuration instead of project-level sequence configuration or to override project level sequence configuration on a session-by-session basis, if required (see "Configuring Sequencing at the Session Level").
To tell TopLink into which table and column to write the sequence value when an instance of a descriptor's reference class is created, you configure TopLink sequencing at the descriptor level (see "Configuring Sequencing at the Descriptor Level").
As defined in http://www.w3.org/TR/REC-xml-names/, an XML namespace is a collection of names, identified by a URI reference, which are used in XML documents as element types and attribute names. To promote reusability and modularity, XML document constructs should have universal names, whose scope extends beyond their containing document. XML namespaces are the mechanism which accomplishes this.
XML namespaces are applicable in projects that reference an XML schema: EIS projects that use XML records (see "EIS Projects") and XML projects (see "XML Projects").
For more information, see "Understanding XML Namespaces".
Use a relational project for transactional persistence of Java objects to a conventional relational database (see "Building Relational Projects for a Relational Database") or to an object-relational database that supports data types specialized for object storage (see "Building Relational Projects for an Object-Relational Database"), both accessed using JDBC.
Note: If you are using TopLink Workbench, you must add your JDBC driver to the TopLink Workbench classpath. If you are using TopLink Workbench and direct to XML type mappings (see "Direct-to-XMLType Mapping"), you must add the Oracle Databasexdb.jar file to the TopLink Workbench classpath.
For more information, see "Configuring the TopLink Workbench Environment". |
In a relational project, you can make full use of TopLink queries and expressions (see Chapter 93, "Understanding TopLink Queries").
TopLink Workbench provides complete support for creating relational projects that map Java objects to a conventional relational database accessed using JDBC.
Table 17-3 describes the components of a relational project for a relational database.
Table 17-3 Components of a Relational Project for a Relational Database
Component | Supported Types |
---|---|
Data Source |
For more information, see the following: |
Descriptors |
For more information, see "Relational Descriptors". |
Mappings |
For more information, see the following: |
TopLink Workbench does not currently support relational projects for an object-relational database. You must create such a relational project in Java.
Using Java, you can create a relational project for transactional persistence of Java objects to an object-relational database that supports data types specialized for object storage (such as Oracle Database) accessed using JDBC.
When using TopLink to build a relational project for an object-relational database, consider the following:
You must create a Java class and a TopLink ObjectRelationalDescriptor
for each structured type (Struct/object-type
)
TopLink supports only arrays (Varrays
) of basic types or arrays on structured types (Struct/object-type
).
TopLink does not support arrays of Refs
or arrays of nested tables.
TopLink supports only nested tables of Refs
.
TopLink does not support nested tables of basic types, structured types, or array types.
The general development process for building a relational project for an object-relational database is as follows:
Define structured object-types in the database.
Define tables of the structured object-types in the database.
Define the Java classes that will map to the structured object-types.
Create a relational project (see "Creating a Project").
Create an object-relational descriptor for each Java class (see "Creating an Object-Relational Descriptor").
Create object-relational mappings from each persistent field of each Java class to the corresponding object-types and object-type tables (see Chapter 47, "Configuring an Object-Relational Mapping").
Table 17-4 describes the components of a relational project for an object-relational database.
Table 17-4 Components of a Relational Project for an Object-Relational Database
Component | Supported Types |
---|---|
Data Source |
For more information, see the following: |
Descriptors |
For more information, see "Object-Relational Descriptors". |
Mappings |
For more information, see the following: |
Use an EIS project for transactional persistence of Java objects to a nonrelational data source accessed using a J2EE Connector Architecture (J2C) adapter and EIS records.
J2C provides a Common Client Interface (CCI) API to access nonrelational EIS. This provides a similar interface to nonrelational data sources as JDBC provides for relational data sources. This API defines several types of nonrelational record types including mapped and indexed. XML has emerged as the standard format to exchange data, and most leading J2C adapter providers have extended the CCI API to define XML data records.
To use a JCA adapter with TopLink EIS, the JCA adapter must support the JCA CCI interface. At run time, your JCA adapter and the Java connector.jar
file (that contains the javax.resource.cci
and javax.resource.spi
interfaces that TopLink EIS uses) must be on your application or application server classpath.
If you are using TopLink Workbench, you must add your JCA adapter to the TopLink Workbench classpath. By default, TopLink Workbench updates its classpath to include the Java 1.5 connector.jar
file from <
TOPLINK_HOME
>/j2ee/home/lib
. If this version of the connector.jar
file is incompatible with your environment, edit the workbench.cmd
or workbench.sh
file in <
TOPLINK_HOME
>/bin
to change the path to this file. For more information, see "Configuring the TopLink Workbench Environment".
EIS includes legacy data sources, enterprise applications, legacy applications, and other information systems. These systems include such sources as Custormer Information Control System (CICS), Virtual Storage Access Method (VSAM), Information Management System (IMS), ADABASE database, and flat files.
Oracle recommends using EIS projects to integrate TopLink with a legacy or nonrelational data source. Other methods of accessing EIS data sources include:
Using a specialized JDBC driver that allows connecting to an EIS system as if it were a relational database. You could use a TopLink relational project with these drivers (see "Relational Projects").
Linking to or integrating with the EIS data from a relational database, such as Oracle Database.
Using a proprietary API to access the EIS system. In this case it may be possible to wrap the API with a J2C CCI interface to allow usage with a TopLink EIS project.
TopLink provides support for mapping Java objects to EIS mapped, indexed, and XML records, through J2C, using the TopLink mappings described in Part XII, "EIS Mappings".
You configure a TopLink EIS descriptor to use a particular EIS record format (see "Configuring Record Format"). TopLink EIS mappings use their EIS descriptor's record format configuration to determine how to map their Java objects to EIS records.
If you use XML records, the TopLink runtime performs XML data conversion based on one or more XML schemas. In an EIS project that uses XML records, TopLink Workbench directly references schemas in the deployment XML, and exports mappings configured with respect to the schemas you specify. For information on how to use TopLink Workbench with XML schemas, see "Working With XML Schemas". For information on how TopLink supports XML namespaces, see "XML Namespaces".
Table 17-5 describes the components of an EIS project.
Table 17-5 EIS Project Components
Component | Supported Types |
---|---|
Data Source |
For more information, see the following: |
Descriptors |
For more information, see "EIS Descriptors". |
Mappings |
For more information, see the following: |
You can create an EIS project with TopLink Workbench for use with EIS XML records (see "Building EIS Projects With XML Records") or you can build an EIS project in Java for use with any supported EIS record type (see "Building EIS Projects With Indexed or Mapped Records").
In an EIS project, your EIS interactions (see "Enterprise Information System (EIS) Interactions") can make full use of TopLink queries (see Chapter 93, "Understanding TopLink Queries"). However, you cannot use TopLink expressions with EIS: in an EIS project, interactions replace expressions.
TopLink Workbench provides complete support for creating EIS projects that map Java objects to EIS XML records.
Using TopLink Workbench, you can create an EIS project for transactional persistence of Java objects to a non-relational data source accessed using a J2C adapter and EIS XML records.
The TopLink runtime performs XML data conversions based on one or more XML schemas. In an EIS project, TopLink Workbench does not directly reference schemas in the deployment XML, but instead exports mappings configured in accordance to specific schemas.
EIS queries use XMLInteraction
. For more information, see "Using EIS Interactions".
TopLink Workbench does not currently support non-XML EIS projects. You must create such an EIS project in Java.
Using Java, you can create an EIS project for transactional persistence of Java objects to a nonrelational data source accessed using a J2C adapter and any supported EIS record type including indexed, mapped, or XML records.
If you use XML records, the TopLink runtime performs XML data conversion based on one or more XML schemas. When you create an EIS project in Java, you configure mappings with respect to these schemas, but the TopLink runtime does not directly reference them.
You can base queries on any supported EIS interaction: IndexedInteraction
, MappedInteraction
(including QueryStringInteraction
), or XMLInteraction
(including XQueryInteraction
). For more information, see "Using EIS Interactions".
Use an XML project for nontransactional, nonpersistent (in-memory) conversions between Java objects and XML documents using JAXB (see "TopLink Support for Java Architecture for XML Binding (JAXB)" and "JAXB Validation"). TopLink Workbench provides complete support for creating XML projects.
The TopLink runtime performs XML data conversion based on one or more XML schemas. In an XML project, TopLink Workbench directly references schemas in the deployment XML, and exports mappings configured with respect to the schemas you specify. For information on how to use TopLink Workbench with XML schemas, see "Working With XML Schemas". For information on how TopLink supports XML namespaces, see "XML Namespaces".
Table 17-6 describes the components of an XML project.
Table 17-6 XML Project Components
Component | Supported Types |
---|---|
Data Source |
None |
Descriptors |
For more information, see "XML Descriptors". |
Mappings |
For more information, see the following: |
In an XML project, you do not use TopLink queries and expressions.
JAXB provides a standard Java object-to-XML API. For more information, see http://java.sun.com/xml/jaxb/index.html
.
TopLink provides an extra layer of functions on top of JAXB. It allows for the creation and subsequent manipulation of mappings (in the form of a TopLink Workbench project) from an existing object model, without requiring the recompilation of the JAXB object model.
An essential component of this function is the TopLink JAXB compiler. Using the TopLink JAXB compiler, you can generate both a TopLink XML project and JAXB-compliant object model classes from your XML schema.
The TopLink JAXB compiler simplifies JAXB application development with TopLink by automatically generating (see "Creating an XML Project From an XML Schema") both the required JAXB files (see "Understanding JAXB-Specific Generated Files") and the TopLink files ("Understanding TopLink-Specific Generated Files") from your XML schema (XSD) document.
For more information on using the JAXB and TopLink-specific files that the TopLink JAXB compiler generates, see "Using TopLink JAXB Compiler Generated Files at Run Time".
The TopLink JAXB compiler generates the following JAXB-specific files from your XSD:
The JAXB runtime uses these files as specified by the JAXB specification.
All JAXB-specific files are generated in the output directory you define, and in the subdirectories implied by the target package name you define. For more information about TopLink JAXB binding compiler options, see "Creating an XML Project From an XML Schema".
Before you compile your generated classes, be sure to configure your integrated development environment (IDE) classpath to include <
ORACLE_HOME
>\lib\xml.jar
. For example, see Chapter 6, "Using an Integrated Development Environment".
All interfaces are named according to the content, element, or implementation name
attribute defined in the XSD.
All implementation classes are named according to the content, element, or implementation name
attribute defined in the XSD and a suffix of Impl
.
The generated implementation classes are simple domain classes, with private attributes for each JAXB property, and public get
and set
methods that return or set attribute values.
The ObjectFactory
class provides an instance factory method for each content and element interface. For example, given an element interface ItemsImpl
, there would be an instance factory method in the ObjectFactory
class with the following signature:
public ItemsImpl createItemsImpl() throws javax.xml.bind.JAXBException
The ObjectFactory
class also provides a dynamic instance factory allocator with the following signature:
public static Object newInstance(Class javaContentInterface) throws javax.xml.bind.JAXBException
The JAXB properties file is named jaxb.properties
and it contains a single entry that defines the javax.xml.bind.context.factory
property with a value equal to the fully qualified class name of the TopLink implementation of JAXBContext
:
javax.xml.bind.context.factory=oracle.toplink.ox.jaxb.JAXBContextFactory
The TopLink JAXB compiler generates the following TopLink-specific files from your XSD:
You use these files to customize the TopLink metadata that corresponds to the generated JAXB-specific objects.
All TopLink-specific files are generated in a subdirectory, named toplink
, of the output directory you specify (see "Creating an XML Project From an XML Schema").
The toplink
subdirectory is organized as Figure 17-1 illustrates.
Figure 17-1 JAXB Binding Compiler Generated Files and Directories
In the generated sessions.xml
file, the name
element is the name of the context path and the project-xml
element is the name of the generated project XML file.
Example 17-1 shows a typical sessions.xml
file where the context path is examples.ox.model
.
Example 17-1 Typical Generated sessions.xml File
<?xml version="1.0" encoding="US-ASCII"?> <toplink-sessions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file://xsd/sessions_10_0_3.xsd" version="0"> <session xsi:type="database-session"> <name>customer_example</name> <primary-project xsi:type="xml">purchaseOrder.xml</primary-project> <login xsi:type="xml-login"> <platform-class>oracle.toplink.ox.platform.SAXPlatform</platform-class> </login> </session> </toplink-sessions>
As in any TopLink project, the TopLink session is your primary facade to the TopLink XML API (see "Using TopLink JAXB Compiler Generated Files at Run Time").
The project XML file is named the same as the XSD, but with a file extension of xml
. In Figure 17-1, the name of the generated project XML file is purchaseOrder.xml
.
The project XML file contains a descriptor and associated mappings for each content, element, and implementation class.
The TopLink Workbench project is written to a subdirectory as Figure 17-1 illustrates. This subdirectory contains a TopLink Workbench project file named with the same name as the XSD, but with a file extension of mwp
and the required descriptor
and class
subdirectories. In Figure 17-1, the TopLink Workbench project is named purchaseOrder.mwp
.
Optionally, you can use this TopLink Workbench project to customize the generated descriptors and mappings and reexport the project XML file.
The TopLink JAXB compiler will generate a single class called DescriptorAfterLoads
if any implementation class contains a mapping to a type safe enumeration (see "Mappings and JAXB Typesafe Enumerations").
The TopLink JAXB compiler will update this DescriptorAfterLoads
class with a descriptor amendment method called amend<
ImplementationClassName
>
for each implementation class that contains a mapping to a typesafe enumeration. The amendment method sets an instance of JAXBTypesafeEnumConverter
on each mapping that maps to a typesafe enumeration in that implementation class.
The TopLink Workbench project that the TopLink JAXB compiler creates (see "TopLink Workbench Project") configures the implementation class descriptor with this amendment method. You can open the generated TopLink Workbench project and regenerate deployment XML without losing support for this feature.
At run time, you can access the TopLink JAXB compiler-generated files:
TopLink provides an XMLContext
class with which you can create instances of TopLink XMLMarshaller
, XMLUnmarshaller
, and XMLValidator
.
The XMLContext
is thread-safe. For example, if multiple threads accessing the same XMLContext
object request an XMLMarshaller
, each will receive their own instance of XMLMarshaller
, so any state that the XMLMarshaller
maintains will be unique to that process. The same is true of instances of XMLUnmarshaller
and XMLValidator
.
By using the XMLContext
, you can use TopLink XML in multithreaded architectures, such as the binding layer for Web services.
To use the TopLink XMLContext
, do the following:
Configure your application classpath to include your domain object class files (see "Understanding JAXB-Specific Generated Files") and the TopLink runtime.
Acquire the session manager (see "Acquiring the Session Manager").
Use the session manager to acquire your XML session using the sessions.xml
file you generated with the TopLink JAXB compiler (see "Acquiring a Session From the Session Manager").
Get the XML project instance from the session:
Project myProject = session.getProject();
Create a TopLink XML context instance with the project:
XMLContext context = new XMLContext(myProject);
Use the XMLContext
to create a TopLink XMLMarshaller
, XMLUnmarshaller
, and XMLValidator
:
XMLMarshaller marshaller = context.createMarshaller(); marshaller.marshal(myObject, outputStream); marshaller.setFormattedOutput(true); XMLUnmarshaller unmarshaller = context.createUnmarshaller(); Employee emp = (Employee)unmarshaller.unmarshal(new File("employee.xml")); XMLValidator validator = context.createValidator(); boolean isValid = validator.validate(emp);
You can create an instance of JAXBContext
using the target package name you selected for your generated files (see "Understanding JAXB-Specific Generated Files") as the context path, as Example 17-2 shows. This example assumes that you configure your application classpath to include your domain object class files.
The JAXBContext
is thread-safe.
TopLink can validate both complete object trees and subtrees against the XML schema that was used to generate the implementation classes. In addition, TopLink will validate both root objects (objects that correspond to the root element of the XML document) and nonroot objects against the schema used to generate the object's implementation class.
When validating an object tree, TopLink performs the following checks (in order):
Check that element appears in the document at the specified location.
If maxOccurs or minOccurs is specified, check number of elements.
If type is specified, check that element value satisfies the type constraints.
If a fixed value is specified, check that the element value matches it.
If restrictions (length, patterns, enumerations, and so on) are specified, check that the element value satisfies it.
If an ID type is specified during a validateRoot
operation, check that the ID value is unique in the document.
If an IDREF type is specified during a validateRoot
operation, check that the ID referenced exists in the document.
If validation errors are encountered, TopLink stops validating the object tree and creates a ValidationEvent
object, according to the JAXB specification. If an error occurs in a subobject, TopLink will not validate further down that object's subtree.
For more information on using TopLink XML to perform validation, see "Using TopLink JAXB Compiler Generated Files at Run Time".
For additional information on JAXB and validation, refer to the JAXB specification at http://java.sun.com/xml/jaxb/
.
This section describes the following:
There is only one type of project: oracle.toplink.sessions.Project
.
In an relational project, you store persistent objects for your application in database tables that represent the class of instantiated object. As Figure 17-2 shows, each row of the VEHICLE_POOL table represents an instantiated object from that class, and the VEH_ID column holds the primary key for each object.
Figure 17-2 Sequencing Elements in a Class Database Table
You configure TopLink sequencing at the project or session level (see "Configuring Sequencing at the Project Level" or "Configuring Sequencing at the Session Level") to tell TopLink how to obtain values for the primary key column: that is, what type of sequencing to use (see "Sequencing Types").
You configure TopLink sequencing at the descriptor level (see "Configuring Sequencing at the Descriptor Level") to tell TopLink into which table and column to write the sequence value when an instance of a descriptor's reference class is created.
This section describes the following:
You can configure sequencing using either TopLink Workbench or Java (but not both).
Using TopLink Workbench, create one sequence with a single preallocation size that applies to all descriptors that require sequencing. You can configure table sequencing (see "Table Sequencing") or native sequencing (see "Native Sequencing With an Oracle Database Platform"). If you choose table sequencing, you can either use default table and column names or specify your own (see "Default Versus Custom Sequence Table"). Oracle recommends using TopLink Workbench to configure sequencing. Using TopLink Workbench, you can easily configure the sequencing options applicable to most applications. For more information, see "Configuring Sequencing at the Project Level" or "Configuring Sequencing at the Session Level".
Using Java, you can configure any sequence type that TopLink supports (see "Sequencing Types"). You can create any number and combination of sequences per project. You can create a sequence object explicitly or use the platform default sequence (see "Default Sequencing"). You can associate the same sequence with more than one descriptor or associate different sequences (and different sequence types) to various descriptors. You can configure a separate preallocation size for each descriptor's sequence. For more information, see "Using Java".
TopLink supports the following sequence types:
With table sequencing, you create a single database table that includes sequencing information for one or more sequenced objects in the project. TopLink maintains this table to track sequence numbers for these object types.
As Figure 17-3 shows, the table may contain sequencing information for more than one class that uses sequencing. The default table is called SEQUENCE
and contains two columns:
SEQ_NAME
, which specifies the class type to which the selected row refers
SEQ_COUNT
, which specifies the highest sequence number currently allocated for the object represented in the selected row
The rows of the SEQUENCE
table represent each sequence object: one for each class that participates in sequencing or a single sequence object across several classes so that they can benefit from the same preallocation pool. When you configure sequencing at the descriptor level (see "Configuring Sequencing at the Descriptor Level"), you specify the SEQ_NAME
for the class. Add a row with that name to the SEQUENCE
table and initialize the SEQ_COUNT
column to the value 0
.
Each time a new instance of a class is created, TopLink obtains the required sequence value. For efficiency, TopLink uses preallocation to reduce the number of table accesses required to obtain sequence values (see "Sequencing and Preallocation Size").
You can create the SEQUENCE
table on the database in one of two ways:
Use TopLink Workbench to create the table. See "Generating Tables on the Database" for more information.
Use the TopLink table creator to create and update the table manually. See "Generating SQL Creation Scripts" for more information.
You can configure table sequencing using TopLink Workbench or Java. Oracle recommends that you use TopLink Workbench. For more information about configuring table sequencing, see "Configuring Sequencing at the Project Level" or "Configuring Sequencing at the Session Level".
In most cases, you implement table sequencing using the default table and column names. However, you may want to specify your own table and column names if:
You want to use an existing sequence table for sequencing.
You do not want to use the default naming convention for the table and its columns.
Although similar to table sequencing (see "Table Sequencing"), with unary table sequencing, you create a separate sequence table for each sequenced object in the project.
As Figure 17-4 shows, sequencing information appears in the table for a single class that uses sequencing. You can name the table anything you want but it must contain only one column named (by default) SEQUENCE
.
Figure 17-4 TopLink Unary Table Sequence Table
When you configure sequencing at the descriptor level, you specify the sequence name for the class: this is the name of the unary table sequence table. Figure 17-4 shows a unary table sequence for the Employee
class. The Employee
class descriptor is configured (see "Configuring Sequencing at the Descriptor Level") with a sequence name of EMP_SEQ
to match the unary table sequence table name. TopLink adds a row to this table and initializes the SEQUENCE
column to the value 1
.
Each time a new class is created, TopLink obtains the required sequence value from the single row of the unary sequence table corresponding to the class. For efficiency, TopLink uses preallocation to reduce the number of table accesses required to obtain sequence values (see "Sequencing and Preallocation Size").
You can create the unary table sequence table on the database in one of two ways:
Use TopLink Workbench to create the table. See "Generating Tables on the Database" for more information.
Use the TopLink table creator to create and update the table manually. See "Generating SQL Creation Scripts" for more information.
If you are migrating a BEA WebLogic CMP application to OC4J and TopLink persistence (see "Migrating BEA WebLogic Persistence to OC4J TopLink Persistence"), the TopLink migration tool does not migrate BEA WebLogic single column sequence tables to TopLink unary sequence tables (see "Unary Table Sequencing"). After migration, you must manually configure your project to use TopLink unary sequence tables if your application originally used single column sequence tables in BEA WebLogic.
Currently, you can only configure unary table sequencing in Java using the UnaryTableSequence
class (for more information, see "Using Java").
With query sequencing, you can access a sequence resource using custom read (ValueReadQuery
) and update (DataModifyQuery
) queries and a preallocation size that you specify. This allows you to perform sequencing using stored procedures and allows you to access sequence resources that are not supported by the other sequencing types that TopLink provides.
Currently, you can only configure query sequencing in Java using the QuerySequence
class (for more information, see "Configuring Query Sequencing").
The platform owned by a login is responsible for providing a default sequence instance appropriate for the platform type. For example, by default, a DatabasePlatform
provides a table sequence using the default table and column names (see "Table Sequencing").
You can access this default sequence directly using DatasourceLogin
method getDefaultSequence
, or indirectly by using the DefaultSequence
class, a wrapper for the platform default sequence.
If you associate a descriptor with a nonexistent sequence, the TopLink runtime will create an instance of DefaultSequence
to provide sequencing for that descriptor. For more information, see "Configuring the Platform Default Sequence".
The main purpose of the DefaultSequence
is to allow a sequence to use a different pre-allocation size than the project default.
Currently, you can only make use of default sequencing in Java (for more information, see "Using the Platform Default Sequence").
TopLink support for native sequencing with Oracle databases is similar to table sequencing (see "Table Sequencing"), except that TopLink does not maintain a table in the database. Instead, the database contains a sequence object that stores the current maximum number and preallocation size for sequenced objects. The sequence name configured at the descriptor level identifies the sequence object responsible for providing sequencing values for the descriptor's reference class.
You can configure native sequencing using TopLink Workbenchor Java. Oracle recommends that you use TopLink Workbench. For more information about configuring table sequencing, see "Configuring Sequencing at the Project Level" or "Configuring Sequencing at the Session Level".
The Oracle SEQUENCE
object implements a strategy that closely resembles TopLink sequencing: it implements an INCREMENT
construct that parallels the TopLink preallocation size, and a sequence.nextval
construct that parallels the SEQ_COUNT
field in the TopLink SEQUENCE
table in table sequencing. This implementation enables TopLink to use the Oracle SEQUENCE
object as if it were a TopLink SEQUENCE
table, but eliminates the need for TopLink to create and maintain the table.
As with table sequencing, TopLink creates a pool of available numbers by requesting that the Oracle SEQUENCE
object increment the sequence.nextval
and return the result. Oracle adds the value, INCREMENT
, to the sequence.nextval
, and TopLink uses the result to build the sequencing pool.
The key difference between this process and the process involved in table sequencing is that TopLink is unaware of the INCREMENT
construct on the SEQUENCE
object. TopLink sequencing and the Oracle SEQUENCE
object operate in isolation. To avoid sequencing errors in the application, set the TopLink preallocation size and the Oracle SEQUENCE
object INCREMENT
to the same value. Note that the Oracle sequence object must have a starting value equal to the preallocation size because when TopLink gets the next sequence value, it assume it has the previous preallocation size of values.
Your database administrator (DBA) must create a SEQUENCE
object on the database for every sequencing series your application requires. If every class in your application requires its own sequence, the DBA creates a SEQUENCE
object for every class; if you design several classes to share a sequence, the DBA need create only one SEQUENCE
object for those classes.
For example, in Figure 17-5, consider the case of a sporting goods manufacturer that manufactures three styles of tennis racquet. The data for these styles of racquet are stored in the database as follows:
Each style of racquet has its own class table.
Each manufactured racquet is an object represented by a line in the class table.
The system assigns serial numbers to the racquets that use sequencing.
Figure 17-5 Example of Database Tables–Racquet Information
The manufacturer can do either of the following:
Use separate sequencing for each racquet style. The DBA builds three separate SEQUENCE
objects, perhaps called ATTACK_SEQ
, VOLLEY_SEQ
, and PROX_SEQ
. Each different racquet line has its own serial number series, and there may be duplication of serial numbers between the lines (for example: all three styles may include a racquet with serial number 1234).
Use a single sequencing series for all racquets. The DBA builds a single SEQUENCE
object (perhaps called RACQUET_SEQ
). The manufacturer assigns serial numbers to racquets as they are produced, without regard for the style of racquet.
Several databases support a type of native sequencing in which the database management system generates the sequence numbers.
When you create a database table for a class that uses native sequencing, include a primary key column, and set the column type as follows:
For Sybase and Microsoft SQL Server databases, set the primary key field to the type IDENTITY
.
For IBM Informix databases, set the primary key field to the type SERIAL
.
Note: TopLink does not support native sequencing in IBM DB2 databases. |
When you insert a new object into the table, TopLink populates the object before insertion into the table, but does not include the sequence number. As the database inserts the object into its table, the database automatically populates the primary key field with a value equal to the primary key of the previous object plus 1
.
At this point, and before the transaction closes, TopLink reads back the primary key for the new object so that the object has an identity in the TopLink cache.
Note: This type of sequencing does not support preallocation, so the preallocation size must be set to 1. To take advantage of sequence preallocation, Oracle recommends that you use table sequencing on these databases instead of native sequencing. |
If your database provides native sequencing, but TopLink does not directly support it, you may be able to access the native sequence object using a query sequence and stored procedures. For more information, see "Query Sequencing".
You can configure native sequencing using TopLink Workbenchor Java. Oracle recommends that you use TopLink Workbench. For more information about configuring table sequencing, see "Configuring Sequencing at the Project Level" or "Configuring Sequencing at the Session Level".
To improve sequencing efficiency, TopLink lets you preallocate sequence numbers. Preallocation enables TopLink to build a pool of available sequence numbers that are assigned to new objects as they are created and inserted into the database. TopLink assigns numbers from the sequence pool until the pool is empty.
The preallocation size specifies the size of the pool of available numbers. Preallocation improves sequencing efficiency by substantially reducing the number of database accesses required by sequencing. By default, TopLink sets preallocation size to 50
. You can specify preallocation size either in TopLink Workbench or as part of the session login.
Preallocation size configuration applies to table sequencing and Oracle native sequencing. In Oracle native sequencing, the sequence preallocation size must match the Oracle sequence object increment size. Preallocation is not available for native sequencing in other databases as they use an auto-assigned sequence column. Oracle recommends that you use table sequencing in non-Oracle databases to allow preallocation.
For table sequencing, TopLink maintains a pool of preallocated values for each sequenced class. When TopLink exhausts this pool of values, it acquires a new pool of values, as follows:
TopLink accesses the database, requesting that the SEQ_COUNT
for the given class (identified by the SEQ_NAME
) be incremented by the preallocation size and the result returned.
For example, consider the SEQUENCE
table in Figure 17-3. If you create a new purchase order and TopLink has exhausted its pool of sequence numbers, then TopLink executes a SQL statement to increment SEQ_COUNT
for SEQ_PURCH_ORDER
by the preallocation size (in this case, the TopLink default of 50
). The database increments SEQ_COUNT
for SEQ_PURCH_ORDER
to 1600
and returns this number to TopLink.
TopLink calculates a maximum and a minimum value for the new sequence number pool, and creates the pool of values.
TopLink populates the object sequence attribute with the first number in the pool and writes the object to the class table.
As you add new objects to the class table, TopLink continues to assign values from the pool until it exhausts the pool. When the pool is exhausted, TopLink again requests new values from the table.
Using TopLink Workbench, you specify a preallocation size when you choose a sequencing type at the project or session level. That preallocation size applies to all descriptors.
Using Java, you can specify a different preallocation size for each sequence that you create.
For more information about configuring preallocation size, see "Configuring Sequencing at the Project Level" or "Configuring Sequencing at the Session Level".
To implement sequencing for entity beans with container-managed persistence, use a sequencing strategy that implements preallocation, such as table sequencing or Oracle native sequencing. Preallocation ensures that the entity bean primary key is available at the ejbPostCreate
method. If you use non-Oracle native sequencing (for example, Sybase, Microsoft SQL Server, or Informix database native sequencing), be aware that:
Non-Oracle native sequencing does not strictly conform to any EJB specification, because it does not initialize the primary key for a created object until you commit the transaction that creates the object. EJB specifications prior to 3.0 expect that the primary key is available at ejbPostCreate
method.
TopLink CMP integration for IBM WebSphere application server does not support native sequencing other than Oracle native sequencing.
OC4J and BEA WebLogic Server supports native sequencing; however, this type of native sequencing does not assign or return a primary key for a created object until you commit the transaction in which the object is created. Because of this, if you use native sequencing, commit a transaction immediately after calling the ejbCreate
method to avoid problems with object identity in the TopLink cache and the container.
TopLink CMP Integration With IBM WebSphere Application Server
The TopLink CMP integration with IBM WebSphere application server does not automatically provide the primary key after calling the ejbCreate
method. If you deploy to a IBM WebSphere application server, explicitly set the primary key in the ejbCreate
method. Example 17-3 illustrates this call in a WebSphere integration.
Example 17-3 Setting Primary Key in IBM WebSphere
public Integer ejbCreate() throws CreateException { oracle.toplink.ejb.cmp.was.SessionLookupHelper.getHelper().getSession(this) .getActiveUnitofWork().assignSequenceNumber(this); return null }
This example uses the TopLink SessionLookupHelper
to look up the correct session and uses the session to assign a sequence number to the bean.
TopLink CMP Integration With OC4J and BEA WebLogic Server
In the TopLink CMP integration with OC4J and BEA WebLogic Server, TopLink automatically sets the primary key field on the bean. You do not pass the key value as a parameter to the create
method, nor set them in the create
method. Example 17-4 illustrates this call in a WebLogic integration.
Example 17-4 Setting Primary Key in OC4J and BEA WebLogic
public Integer ejbCreate() throws CreateException { return null; }
If you are migrating a BEA WebLogic CMP application to OC4J and TopLink persistence (see "Migrating BEA WebLogic Persistence to OC4J TopLink Persistence"), the TopLink migration tool automatically configures your project to use unary table sequencing (see "Unary Table Sequencing") if your application originally used single-column sequence tables in BEA WebLogic.
As defined in http://www.w3.org/TR/REC-xml-names/, an XML namespace is a collection of names, identified by a URI reference, which are used in XML documents as element types and attribute names. To promote reusability and modularity, XML document constructs should have universal names, whose scope extends beyond their containing document. XML namespaces are the mechanism which accomplishes this.
XML namespaces are applicable in projects that reference an XML schema: EIS projects that use XML records (see "EIS Projects") and XML projects (see "XML Projects").
This section describes the following:
Using TopLink Workbench, you can configure the XML schema namespace for your project. For more information, see "Configuring XML Schema Namespace".
The xsd:schema
element provides attributes that you can use to specify how elements and attributes should be qualified by namespace.
This section describes the consequences of the following combinations of element and attribute form configuration:
Example 17-5 shows an XML schema in which a target namespace is set. It is coded with elementFormDefault
set to qualified
and attributeFormDefault
set to unqualified
. This means all elements must be namespace qualified and globally declared attributes must be namespace qualified and locally defined attributes must not be namespace qualified.
Example 17-5 XML Schema with Element Form Default Qualified and Attribute Form Default Unqualified
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns="urn:namespace-example" targetNamespace="urn:namespace-example"> <xsd:element name="customer" type="customer-type"/> <xsd:complexType name="customer-type"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element ref="date-of-birth"/> </xsd:sequence> <xsd:attribute name="id" type="xsd:integer"/> </xsd:complexType> <xsd:element name="date-of-birth" type="xsd:date"/> </xsd:schema>
Example 17-6 shows an XML document that conforms to this XML schema.
Example 17-6 XML Document
<?xml version="1.0" encoding="UTF-8"?> <ns:customer xmlns:ns="urn:namespace-example" id="1"> <ns:name>Jane Doe</ns:name> <ns:date-of-birth>1975-02-21</ns:date-of-birth> </ns:customer>
Example 17-7 shows the Java code for a Customer
class XMLDescriptor
and XML mappings for its attributes to illustrate how this schema configuration affects the XPaths you specify for default root element and mappings (for more information, see "Configuring an XML Descriptor" and Chapter 63, "Configuring an XML Mapping").
Example 17-7 XML Descriptors and Mappings
NamespaceResolver namespaceResolver = new NamespaceResolver(); namespaceResolver.put("ns", "urn:namespace-example"); XMLDescriptor customerDescriptor = new XMLDescriptor(); customerDescriptor.setJavaClass(Customer.class); customerDescriptor.setDefaultRootElement("ns:customer"); customerDescriptor.setNamespaceResolver(namespaceResolver); XMLDirectMapping idMapping = new XMLDirectMapping(); idMapping.setAttributeName("id"); idMapping.setXPath("@id"); customerDescriptor.addMapping(idMapping); XMLDirectMapping nameMapping = new XMLDirectMapping(); nameMapping.setAttributeName("name"); nameMapping.setXPath("ns:name/text()"); customerDescriptor.addMapping(nameMapping); XMLDirectMapping birthDateMapping = new XMLDirectMapping(); birthDateMapping.setAttributeName("birthDate"); birthDateMapping.setXPath("ns:date-of-birth/text()"); customerDescriptor.addMapping(birthDateMapping);
Example 17-8 shows an XML schema in which a target namespace is set. It is coded with elementFormDefault
and attributeFormDefault
set to unqualified
. This means that globally defined nodes must be namespace qualified and locally defined nodes must not be namespace qualified.
Example 17-8 XML Schema with Element and Attribute Form Default Unqualified
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified" attributeFormDefault="unqualified" xmlns="urn:namespace-example" targetNamespace="urn:namespace-example"> <xsd:element name="customer" type="customer-type"/> <xsd:complexType name="customer-type"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element ref="date-of-birth"/> </xsd:sequence> <xsd:attribute name="id" type="xsd:integer"/> </xsd:complexType> <xsd:element name="date-of-birth" type="xsd:date"/> </xsd:schema>
Example 17-9 shows an XML document that conforms to this XML schema.
Example 17-9 XML Document
<?xml version="1.0" encoding="UTF-8"?> <ns:customer xmlns:ns="urn:namespace-example" id="1"> <name>Jane Doe</name> <ns:date-of-birth>1975-02-21</ns:date-of-birth> </ns:customer>
Example 17-10 shows the Java code for a Customer
class XMLDescriptor
and XML mappings for its attributes to illustrate how this schema configuration affects the XPaths you specify for default root element and mappings (for more information, see "Configuring an XML Descriptor" and Chapter 63, "Configuring an XML Mapping").
Example 17-10 XML Descriptors and Mappings
NamespaceResolver namespaceResolver = new NamespaceResolver(); namespaceResolver.put("ns", "urn:namespace-example"); XMLDescriptor customerDescriptor = new XMLDescriptor(); customerDescriptor.setJavaClass(Customer.class); customerDescriptor.setDefaultRootElement("ns:customer"); customerDescriptor.setNamespaceResolver(namespaceResolver); XMLDirectMapping idMapping = new XMLDirectMapping(); idMapping.setAttributeName("id"); idMapping.setXPath("@id"); customerDescriptor.addMapping(idMapping); XMLDirectMapping nameMapping = new XMLDirectMapping(); nameMapping.setAttributeName("name"); nameMapping.setXPath("name/text()"); customerDescriptor.addMapping(nameMapping); XMLDirectMapping birthDateMapping = new XMLDirectMapping(); birthDateMapping.setAttributeName("birthDate"); birthDateMapping.setXPath("ns:date-of-birth/text()"); customerDescriptor.addMapping(birthDateMapping);
Example 17-11 shows an XML schema in which a target namespace is set. It is coded with elementFormDefault
and attributeFormDefault
set to qualified. This means that all nodes must be namespace qualified.
Example 17-11 XML Schema with Element and Attribute Form Default Qualified
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified" xmlns="urn:namespace-example" targetNamespace="urn:namespace-example"> <xsd:element name="customer" type="customer-type"/> <xsd:complexType name="customer-type"> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element ref="date-of-birth"/> </xsd:sequence> <xsd:attribute name="id" type="xsd:integer"/> </xsd:complexType> <xsd:element name="date-of-birth" type="xsd:date"/> </xsd:schema>
Example 17-12 shows an XML document that conforms to this XML schema.
Example 17-12 XML Document
<?xml version="1.0" encoding="UTF-8"?> <ns:customer xmlns:ns="urn:namespace-example" ns:id="1"> <ns:name>Jane Doe</ns:name> <ns:date-of-birth>1975-02-21</ns:date-of-birth> </ns:customer>
Example 17-13 shows the Java code for a Customer
class XMLDescriptor
and XML mappings for its attributes to illustrate how this schema configuration affects the XPaths you specify for default root element and mappings (for more information, see "Configuring an XML Descriptor" and Chapter 63, "Configuring an XML Mapping").
Example 17-13 XML Descriptors and Mappings
NamespaceResolver namespaceResolver = new NamespaceResolver(); namespaceResolver.put("ns", "urn:namespace-example"); XMLDescriptor customerDescriptor = new XMLDescriptor(); customerDescriptor.setJavaClass(Customer.class); customerDescriptor.setDefaultRootElement("ns:customer"); customerDescriptor.setNamespaceResolver(namespaceResolver); XMLDirectMapping idMapping = new XMLDirectMapping(); idMapping.setAttributeName("id"); idMapping.setXPath("@ns:id"); customerDescriptor.addMapping(idMapping); XMLDirectMapping nameMapping = new XMLDirectMapping(); nameMapping.setAttributeName("name"); nameMapping.setXPath("ns:name/text()"); customerDescriptor.addMapping(nameMapping); XMLDirectMapping birthDateMapping = new XMLDirectMapping(); birthDateMapping.setAttributeName("birthDate"); birthDateMapping.setXPath("ns:date-of-birth/text()"); customerDescriptor.addMapping(birthDateMapping);
It is common for an XML document to include one or more namespaces. TopLink supports this using its NamespaceResolver
. The namespace resolver maintains pairs of namespace prefixes and Uniform Resource Identifiers (URIs). TopLink uses these prefixes in conjunction with the XPath statements you specify on EIS mappings to XML records and XML mappings.
Although TopLink captures namespace prefixes in the XPath statements for mappings (if applicable), the input document is not required to use the same namespace prefixes. As Example 17-13 shows, TopLink will use the namespace prefixes specified in the mapping when creating new documents.