TopLink can transform data between an object representation and a representation specific to a data source. This transformation is called mapping and it is the core of a TopLink project.
A mapping corresponds to a single data member of a domain object. It associates the object data member with its data source representation and defines the means of performing the two-way conversion between object and data source.
This chapter includes the following sections:
Table 17-1 describes the mapping types that TopLink supports.
Table 17-1 TopLink Mapping Types
Type | Description | Oracle JDeveloper |
TopLink Workbench | Java |
---|---|---|---|---|
Relational (see Section 17.4, "Relational Mappings") |
Mappings that transform any object data member type to a corresponding relational database (SQL) data source representation in any supported relational database. Relational mappings allow you to map an object model into a relational data model. |
|||
Object-relational data type (see Section 17.5, "Object-Relational Data Type Mappings") |
Mappings that transform certain object data member types to structured data source representations optimized for storage in specialized object-relational data type databases, such as Oracle Database. Object-relational data type mappings let you map an object model into an object-relational data type data model. |
|||
EIS (see Section 17.7, "EIS Mappings") |
Mappings that transform object data members to the EIS record format defined by the object's descriptor. |
|||
XML (see Section 17.6, "XML Mappings") |
Mappings that transform object data members to the XML elements of an XML document whose structure is defined by an XML schema document (XSD). |
For more information, see the following:
This section describes concepts unique to TopLink mappings, including the following:
Mapping Architecture (applicable to relational and nonrelational mappings)
Example Mapping (applicable to relational and nonrelational mappings)
JPA Automapping (applicable to relational mappings)
Automapping with TopLink Workbench at Development Time (applicable to relational and nonrelational mappings)
Default Mapping in EJB 2.n CMP Projects Using OC4J at Run Time (applicable to relational mappings)
JAXB Project Generation at Development Time (applicable to XML mappings)
Indirection (Lazy Loading) (applicable to relational mappings)
Method Accessors and Attribute Accessors (applicable to relational and nonrelational mappings)
Mapping Converters and Transformers
Serialized Object Converter (applicable to relational and nonrelational mappings)
Type Conversion Converter (applicable to relational and nonrelational mappings)
Object Type Converter (applicable to XML mappings)
Simple Type Translator (applicable to XML mappings)
Transformation Mappings (applicable to relational and nonrelational mappings)
Mappings and XPath (applicable to XML mappings)
Mappings and xsd:list and xsd:union Types (applicable to XML mappings)
Mappings and the jaxb:class Customization (applicable to XML mappings)
Mappings and JAXB Typesafe Enumerations (applicable to XML mappings)
To define a mapping, you draw upon the following components:
The data representation specific to the data source (such as a relational database table or schema-defined XML element) in which you store the object's data.
A descriptor for a particular object class.
An object class to map.
Note:
A mapping is the same regardless of whether your project is persistent or nonpersistent.For an example of a typical TopLink mapping, see Section 17.2.2, "Example Mapping".
The type of data source you define in your TopLink project determines the type of mappings you can use and how you configure them. In a persistent project, you use mappings to persist to a data source. In a nonpersistent project, you use mappings simply to transform between the object format and some other data representation (such as XML). For more information about data source and project types, see Section 15.1, "TopLink Project Types".
A descriptor represents a particular domain object: it describes the object's class. It owns mappings: one mapping for each of the class data members that you intend to persist or transform in memory.
Note:
Persistence is applicable at the descriptor level.For more information about descriptors, see Chapter 16, "Introduction to Descriptors".
TopLink provides mappings to handle a wide variety of data types and data representations. For more information, see Section 17.1, "Mapping Types".
All mappings are subclasses of the oracle.toplink.mappings.DatabaseMapping
class. For more information about the mapping API, see Section 17.3, "Mapping API".
Although TopLink supports more complex mappings, most TopLink classes map to a single database table or XML element that defines the type of information available in the class. Each object instance of a given class maps to a single row comprising the object's attributes, plus an identifier (the primary key) that uniquely identifies the object.
Figure 17-1 illustrates the simplest database mapping case in which:
Table_X in the database represents Class_X.
Object_X1 and Object_X2 are instances of Class_X.
Individual rows in Table_X represent Object_X1 and Object_X2, as well as any other instances of Class_X.
Figure 17-1 How Classes and Objects Map to a Database Table
TopLink provides you with the tools to build these mappings, from the simple mappings illustrated in Figure 17-1, to complex mappings.
For an additional example of a relational mapping, see Figure 27-1, "Direct-to-Field Mapping".
For an example of a nonrelational mapping, see Figure 53-34, "XML Transformation Mappings".
Typically, you use Oracle JDeveloper TopLink Editor or TopLink Workbench to define mappings on a class-by-class and data-member-by-data-member basis manually (see Section 120.2, "Creating Mappings Manually During Development").
Alternatively, you can take advantage of the following:
To configure automapping in a JPA project, you just need to annotate your persistence classes with @Entity
and define their primary key with @Id
(or define the list of entities and their primary key fields in your orm.xml
) and the EclipseLink JPA persistence provider will automatically map all unmapped properties. You can also configure persistence.xml
properties to automatically create or replace the corresponding database tables. For more information, see "Introduction to EclipseLink JPA" section of EclipseLink Developer's Guide at http://wiki.eclipse.org/Introduction_to_EclipseLink_JPA_%28ELUG%29
You can use Oracle JDeveloper TopLink Editor Automap feature to automatically define default mappings for every class and data member in your project (see Section 120.3, "Creating Mappings Automatically During Development").
You can use TopLink Workbench Automap feature to automatically define default mappings for every class and data member in your project (see Section 120.3, "Creating Mappings Automatically During Development").
TopLink Workbench automapping is available for all project types and assumes that both the object model and database schema are already defined.
Default mapping is a relational persistence framework term that refers to making the framework automatically generate the object descriptor metadata (including such things as mappings, login data, database platform, locking, and foreign keys).
Note:
You can apply default mapping to relational projects only.TopLink can also optionally create or drop-and-create the tables associated with the entities during the deployment. This means that TopLink can handle the whole deployment process with the minimum requirements: a compliant EAR file and a valid data source. This frees you from creating tables and specifying mappings before you deploy your application.
TopLink default mapping supports the following features:
Direct-to-field mapping support for standard CMP (that is, not dependent object) fields.
Serialized object mapping support for dependent objects.
One-to-one, one-to-many, and many-to-many mappings support for CMR fields.
Self-referencing, unidirectional and bidirectional relationship mappings (see Section 27.2.1, "Directionality").
Optimistic version locking for each entity.
Automatic table drop and create, platform-specified supported types, default size and subsize, and database-reserved keywords.
EJB QL (EJB query language) queries, such as finder and ejbSelect.
Unknown primary key class case (primary key-class type java.lang.Object.class
).
Default mapping is available for CMP relational projects deployed to OC4J configured to use TopLink as the persistence manager. In this configuration, the EJB container provides the entity bean descriptor data (from ejb-jar.xml
) required by the persistence manager to generate the persistence descriptor file.
If a toplink-ejb-jar.xml
descriptor file is not present, TopLink, working as the OC4J persistence manager, generates a default persistence descriptor file for any CMP project during deployment. In this case, TopLink applies default mappings and, optionally, automatic table generation. The generated descriptor file includes the following:
Mapping for each entity CMP and CMR field.
Optimistic locking, foreign keys, target foreign key, and relation table.
Transparent indirection (lazy loading) for relationships.
Database login and platform metadata.
If a toplink-ejb-jar.xml
descriptor file is present and specified in the orion-ejb-jar.xml
file, TopLink does not apply default mapping: it honours the mappings specified in the toplink-ejb-jar.xml
file. In this case, you can still configure automatic table generation.
For more information, see Section 9.9.1.3, "Configuring default-mapping Properties".
JAXB provides an API and a tool that allow automatic two-way mapping between XML documents and Java objects. The JAXB compiler generates all the Java classes and mappings based on the provided Document Type Definition (DTD) and a schema definition.
For more information on JAXB, see Architecture for XML Binding (JAXB): A Primer at http://java.sun.com/developer/technicalArticles/xml/jaxb/index.html
For more information on XML projects, see Chapter 47, "Introduction to XML Projects".
For more information on XML mappings, see Chapter 53, "Introduction to XML Mappings".
By default, when TopLink retrieves a persistent object, it retrieves all of the dependent objects to which it refers. When you configure indirection (also known as lazy reading, lazy loading, and justEinEtime reading) for an attribute mapped with a relationship mapping, TopLink uses an indirection object as a place holder for the referenced object: TopLink defers reading the dependent object until you access that specific attribute. This can result in a significant performance improvement, especially if the application is interested only in the contents of the retrieved object, rather than the objects to which it is related.
Oracle strongly recommends using indirection for all relationship mappings. Not only does this lets you optimize data source access, but it also allows TopLink to optimize the unit of work processing, cache access, and concurrency.
Note:
The use of indirection is especially important for providing a proper maintenance of bidirectional relationships (see Section 2.14.3.4, "Maintaining Bidirectional Relationships"). In this case, you must use indirection. If you are operating with collections, you must use transparent indirection (see Section 17.2.4.2, "Transparent Indirect Container Indirection").Figure 17-2 shows an indirection example. Without indirection, reading the Order
object also reads the dependent collection of LineItem
objects. With indirection, reading the Order
object does not read the dependent collection of LineItem
objects: the lineItems
attribute refers to an indirection object. You can access other attributes (such as customerId
), but TopLink reads the dependent LineItem
objects only if and when you access the lineItems
attribute.
TopLink supports the following types of indirection:
When using indirection with CMP, the version of EJB and application server you use affects how indirection is configured and what types of indirection are applicable (see Section 17.2.4.6, "Indirection and EJB 2.n CMP").
When using indirection with an object that your application serializes, you must consider the effect of any untriggered indirection objects at deserialization time (see Section 17.2.4.7, "Indirection, Serialization, and Detachment").
For information on configuring indirection, see Section 121.3, "Configuring Indirection (Lazy Loading)".
Persistent classes that use indirection must replace relationship attributes with value holder attributes. A value holder is an instance of a class that implements the ValueHolderInterface
interface, such as ValueHolder
. This object stores the information necessary to retrieve the object it is replacing from the database. If the application does not access the value holder, the replaced object is never read from the database.
To obtain the object that the value holder replaces, use the getValue
and setValue
methods of the ValueHolderInterface
. A convenient way of using these methods is to hide the getValue
and setValue
methods of the ValueHolderInterface
inside get
and set
methods, as shown in the following illustrations.
Figure 17-3 shows the Employee
object being read from the database. The Address
object is not read and will not be created unless it is accessed.
The first time the address is accessed, as in Figure 17-4, the ValueHolder
reads and returns the Address
object.
Subsequent requests for the address do not access the database, as shown in Figure 17-5.
If you are using method access (Section 121.6, "Configuring Method or Direct Field Accessing at the Mapping Level"), the get and set methods specified in the mapping must access the instance of ValueHolderInterface
, rather than the object referenced by the value holder. The application should not use these getter and setter, but use the getter and setter that hide the usage of value holders. For more information, see Section 121.3.2.2, "Configuring Value Holder Indirection with Method Accessing".
For JPA entities or POJO classes that you configure for weaving, TopLink weaves value holder indirection for one-to-one mappings. If you want TopLink to weave change tracking and your application includes collection mappings (one-to-many or many-to-many), then you must configure all collection mappings to use transparent indirect container indirection only (you may not configure your collection mappings to use eager loading nor value holder indirection).
Transparent indirect container (see Section 121.14, "Configuring Container Policy") indirection lets you declare any relationship attribute of a persistent class that holds a collection of related objects as any of the following:
java.util.Collection
java.util.Hastable
java.util.List
java.util.Map
java.util.Set
java.util.Vector
TopLink will use an indirection object that implements the appropriate interface and also performs just-in-time reading of the related objects. When using transparent indirection, you do not have to declare the attributes as ValueHolderInterface
.
Newly created collection mappings use transparent indirection by default if their attribute is not a ValueHolderInterface
.
For JPA entities or POJO classes that you configure for weaving, TopLink weaves value holder indirection for one-to-one mappings. If you want TopLink to weave change tracking and your application includes collection mappings (one-to-many or many-to-many), then you must configure all collection mappings to use transparent indirect container indirection only (you may not configure your collection mappings to use eager loading nor value holder indirection).
You can configure TopLink to automatically weave transparent indirect container indirection for JPA entities and Plain Old Java Object (POJO) classes. For more information, see the following:
"Using EclipseLink JPA Weaving" section of EclipseLink Developer's Guide at http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Using_EclipseLink_JPA_Weaving
Introduced in JDK 1.3, the Java class Proxy
lets you use dynamic proxy objects as place-holders for a defined interface. Certain TopLink mappings (see Table 121-4, "Mapping Support for Indirection") can be configured to use proxy indirection, which gives you the benefits of TopLink indirection without the need to include TopLink classes in your domain model. Proxy indirection is to one-to-one relationship mappings as indirect containers are to collection mappings.
To use proxy indirection, your domain model must satisfy all of the following criteria:
The target class of the one-to-one relationship must implement a public interface.
The one-to-one attribute on the source class must be of the interface
type.
If you employ method accessing (Section 121.6, "Configuring Method or Direct Field Accessing at the Mapping Level"), then the getter and setter methods must use the interface.
Before using proxy indirection, be aware of the restrictions it places on how you use the unit of work (see Section 17.2.4.3.1, "Proxy Indirection Restrictions").
To configure proxy indirection, you can use Oracle JDeveloper TopLink Editor, TopLink Workbench (see Section 121.3.1, "How to Configure Indirection Using TopLink Workbench"), or Java in an amendment method (see Section 121.3.2.5, "Configuring Proxy Indirection").
Proxy objects in Java are only able to intercept messages sent. If a primitive operation such as ==
, instanceof
, or getClass
is used on a proxy, it will not be intercepted. This limitation can require the application to be somewhat aware of the usage of proxy objects.
You cannot register the target of a proxy indirection implementation with a unit of work. Instead, first register the source object with the unit of work. This lets you retrieve a target object clone with a call to a getter on the source object clone.
For example:
UnitOfWork uow = session.acquireUnitOfWork(); Employee emp = (Employee)session.readObject(Employee.class); // Register the source object Employee empClone = (Employee)uow.registerObject(emp); // All of source object's relationships are cloned when source object is cloned Address addressClone = empClone.getAddress(); addressClone.setCity("Toronto");
For more information about clones and the unit of work, see Chapter 113, "Introduction to TopLink Transactions".
For JPA entities or POJO classes that you configure for weaving, TopLink weaves value holder indirection for one-to-one mappings. If you want TopLink to weave change tracking and your application includes collection mappings (one-to-many or many-to-many), then you must configure all collection mappings to use transparent indirect container indirection only (you may not configure your collection mappings to use eager loading nor value holder indirection).
For more information, see Section 2.10, "Using Weaving".
When you set mapping annotation attribute fetch
to lazy
, the EclipseLink JPA persistence provider uses indirection.
By default, one-to-many and many-to-many relationships are lazy and use transparent indirection, while one-to-one and many-to-one relationships are not lazy.
If you set one-to-one or many-to-one relationships to lazy, and you enable weaving, the EclipseLink JPA persistence provider will use weaving to enable value holder indirection for these relationships.
For more information, see the following:
When using indirection (lazy loading) with EJB 2.n, how TopLink handles indirection depends on the EJB version and application server you are using.
In addition, you cannot use proxy indirection (see Section 17.2.4.3, "Proxy Indirection") for relationships to an enterprise bean, because EJB do not directly implement their remote or local interfaces.
When using indirection with an enterprise bean that your application serializes, you must consider the effect of any untriggered indirection objects at deserialization time (see Section 17.2.4.7, "Indirection, Serialization, and Detachment").
When using CMP with any of the application servers for which TopLink provides CMP integration (see Section 8.1, "Introduction to the Application Server Support"), TopLink uses code generation to automatically configure the usage of value holder indirection (Section 17.2.4.1, "Value Holder Indirection") for all CMR.
When using indirection (lazy loading), it is likely that a graph of persistent objects will contain untriggered indirection objects. Because indirection objects are transient and do not survive serialization between one JVM and another, untriggered indirection objects will trigger an error if the relationship is accessed after deserialization.
The application must ensure that any indirect relationships that will be required after deserialization have been instantiated before serialization. This can be done through accessing the get method for any relationship using ValueHolder
or weaved indirection, and by sending the size
method to any relationship using transparent indirection. If the application desired the relationships to be always instantiated on serialization, you could overwrite the serialization writeObject
method in the persistent class to first instantiate the desired relationships. Use caution for objects with many or deep relationships to avoid serializing large object graphs: ideally, only the relationships required by the client should be instantiated.
When serializing JPA entities, any lazy relationships that have not been instantiated prior to serialization will trigger errors if they are accessed. If weaving is used on the server, and the entities are serialized to a client, the same weaved classes must exist on the client, either through static weaving of the jar, or through launching the client JVM using the TopLink agent.
For more information, see the following:
By default, TopLink uses direct access to access public attributes. Using TopLink, you can configure field access at the project level (see Section 117.4, "Configuring Method or Direct Field Access at the Project Level") and at the mapping level (Section 121.6, "Configuring Method or Direct Field Accessing at the Mapping Level").
If existing TopLink mappings do not meet your needs, you can create custom mappings using mapping extensions. These extensions include the following:
Note:
You can use the mapping converters and transformers regardless of whether your data source is relational or nonrelational.The serialized object converter is an extension of direct and direct collection mappings that lets you map complex objects into binary fields through Java object serialization. Serialized objects are normally stored in RAW
or Binary Large Object (BLOB)
fields in the database, or HEX
or BASE64
elements in an XML document.
Figure 17-6 shows an example of a direct-to-field mappings that uses a serialized object converter. The attribute jobDescription
contains a formatted text document that is stored in the JOB_DESC
field of the database.
Figure 17-6 Serialized Object Converter (relational)
Figure 17-8 demonstrates an example of a nonrelational mapping that uses a serialized object converter. The attribute jobDescription
contains a formatted text document that TopLink stores in the JOB DESCRIPTION
element of an XML schema.
Figure 17-7 Serialized Object Converter (nonrelational)
The serialized object converter relies on the Java serializer. Before you map a domain object with the serialized object converter, ensure that the domain object implements the java.io.Serializable
interface (or inherits that implementation) and marks all nonserializable fields transient.
For more information, see Section 121.9, "Configuring a Serialized Object Converter".
The type conversion converter is an extension of direct and direct collection mappings that lets you explicitly map a data source type to a Java type. For example, a Number
in the data source can be mapped to a String
in Java, or a java.util.Date
in Java can be mapped to a java.sql.Date
in the data source.
Figure 17-8 illustrates a type conversion mapping (relational). Because the java.util.Date
class is stored by default as a Timestamp
in the database, it must first be converted to an explicit database type such as java.sql.Date
(required only for DB2–most other databases have a single date data type that can store any date or time).
Figure 17-8 Type Conversion Mapping (relational)
Figure 17-9 illustrates a type conversion mapping (nonrelational). java.util.Date
object is mapped to a String in a XML schema.
Figure 17-9 Type Conversion Mapping (nonrelational)
You can use a type conversion converter to specify the specific database type when that type must be handled specially for the database. This includes support for the special Oracle JDBC binding options required for NCHAR
, NVARCHAR2
, and NCLOB
fields as well as the special Oracle Thin JDBC insert and update requirements for handling BLOB
and CLOB
fields greater than 5K.
TopLink uses the NCharacter
, NClob
and NString
types in the oracle.toplink.platform.database.oracle
package as the converter data type to support the NCHAR
, NCLOB
and NVARCHAR2
types. TopLink uses the java.sql.Blob
and Clob
types as the converter data type to support BLOB
and CLOB
values greater than 5K.
You can configure a type conversion converter to map a data source time type (such as TIMESTAMP
) to a java.lang.String
provided that the String value conforms to the following formats:
YYYY/MM/DD HH:MM:SS
YY/MM/DD HH:MM:SS
YYYY-MM-DD HH:MM:SS
YY-MM-DD HH:MM:SS
For more complex String
to TIMESTAMP
type conversion, consider a transformation mapping (see Section 17.2.6.5, "Transformation Mappings").
For more information, see Section 121.10, "Configuring a Type Conversion Converter".
The object type converter is an extension of direct and direct collection mappings that lets you match a fixed number of XML values to Java objects. Use this converter when the values in the schema differ from those in Java.
Figure 17-10 illustrates an object type conversion between the Employee
attribute gender
and the XML element gender
. If the value of the Java object attribute is Female
, TopLink stores it in the XML element as F
.
For more information, see Section 121.11, "Configuring an Object Type Converter".
The simple type translator is an extension of direct and direct collection mappings that lets you automatically translate an XML element value to an appropriate Java type based on the element's <type>
attribute as defined in your XML schema.
You can use a simple type translator only when the mapping's XPath goes to a text node. You cannot use a simple type translator if the mapping's XPath goes to an attribute.
Using a simple type translator, you can make the XML document preserve type information. This is useful when your object model specifies generic object attributes such as java.lang.Object
and java.io.Serializable
, since they do not trigger specific type conversions in TopLink as do specific object attributes such as java.lang.Integer
or java.util.Calendar
.
Figure 17-11 illustrates a type translation XML mapping for the number
attribute of the PhoneNumber
class. Notice that the Java attribute is not specific enough to preserve the typing. The simple type translator adds the type information to the resulting document to preserve the typing.
By default, TopLink uses built-in read and write conversion pairs (see Section 17.2.6.4.1, "Default Read Conversions" and Section 17.2.6.4.2, "Default Write Conversions").
You can override this behavior by specifying and configuring your own simple type translator, for example, to write XML binary data as Base64
.
For more information, see Section 121.12, "Configuring a Simple Type Translator".
Table 17-2 lists the built-in conversion pairs for reading XML elements. When the schema <type>
attribute is specified and the simple type translator is enabled, the value read is converted to the corresponding Java type.
Table 17-2 Simple Type Translator Read Conversions
Schema Type | Java Type |
---|---|
base64Binary |
Byte[] |
boolean |
Boolean |
byte |
Byte |
date |
Calendar |
dateTime |
Calendar |
double |
Double |
float |
Float |
hexBinary |
Byte[] |
int |
int |
integer |
BigInteger |
long |
Long |
short |
Short |
string |
String |
time |
Calendar |
unsignedByte |
Short |
unsignedInt |
Long |
unsignedShort |
Integer |
Table 17-3 lists the built-in conversion pairs for writing XML. When a Java class attribute is of a type in Table 17-3 and the simple type translator is enabled, the corresponding schema type is specified on the element written.
In some special circumstances, existing mapping types and their default Java to data source type handling may be insufficient. In these special cases, you can consider using a transformation mapping to perform specialized translations between how a value is represented in Java and in the data source.
A transformation mapping is made up of the following two components:
attribute transformer (see Section 121.15, "Configuring Attribute Transformer"): performs the object attribute transformation at read (unmarshall) time;
field transformer (see Section 121.16, "Configuring Field Transformer Associations"): performs the object attribute-to-field transformation at write (marshal) time;
You can implement a transformer as either a separate class or as a method on your domain object.
Within your implementation of the attribute and field transformer, you can take whatever actions are necessary to transform your application data to suit your data source, and vise versa.
For more information, see the following:
TopLink uses XPath statements to efficiently map the attributes of a Java object in EIS mappings to XML records, and in XML mappings to XML documents. When you create such a mapping, you can specify the following:
In a relational database table, columns are uniquely identified by name. In an XML document, elements are uniquely identified by name and position. Figure 17-12 illustrates mapping to an XML document in which the first instance of the street
element stores apartment information and the second instance of the street
element stores street information. Figure 17-12 shows that TopLink XML mappings preserve the order in which mappings are persisted and allow you to map Java object attributes to XML elements by position using an XPath like street[2]/text()
.
Other XML technologies only recognize the name of XML elements (not their position) and force you to store the simple values from elements with the same name in a collection.
Figure 17-12 Mapping to an XML Document by Position
In an XML document, attributes and elements are uniquely identified by a combination of name and path. Figure 17-13 illustrates that TopLink XML mappings can uniquely identify an XML element by name and path using an XPath such as item/name/text()
. TopLink does not require a formal object relationship between XML elements lines
and item
.
Other XML technologies force you to provide an object relationship for every level of nesting, resulting in the inclusion of many XML elements and classes simply to organize the data to satisfy this restriction. This produces an unnecessarily large object model that does not properly reflect the domain space.
Figure 17-13 Mapping to an XML Document by Path and Name
For simple XML documents, TopLink XML mappings can correctly place data in an XML document given an XPath of only an attribute or element name.
Figure 17-14 illustrates mapping to a simple XML document by name. You can map Java object attribute name
to XML attribute name
by specifying an XPath of only @NAME
. Similarly, you can map Java object attribute age
to XML text node AGE
by specifying an XPath of only AGE
.
Figure 17-14 Mapping to a Simple XML Document by Name
Specifying an XPath by name provides the worst performance of the XPath mapping options. Oracle recommends that you use XPath by position (see Section 17.2.7.1, "XPath by Position") or XPath by path and name (see Section 17.2.7.2, "XPath by Path and Name") instead.
For composite relationships, TopLink XML mappings can place data in the parent's element rather than an element nested within it given the self XPath ("."
).
Figure 17-15 illustrates mapping to an XML document using the self XPath.
Figure 17-15 Mapping to a XML Document Using Self XPath
Note that in the preceding example represented by Figure 17-15, name
attribute of the Employee
class is mapped using the @name
annotation.
Using the self XPath, you can make TopLink perform all read and write operations in the parent's element and not an element nested within it (see Section 17.2.9, "Mappings and the jaxb:class Customization").
TopLink supports mapping to xsd:list
and xsd:union
types in EIS mappings to XML records and XML mappings to XML documents, as Table 17-4 shows.
Table 17-4 TopLink Support for xsd:list and xsd:union Types
XSD | EIS Direct MappingXML Direct Mapping |
EIS Composite Direct Collection MappingXML Composite Direct Collection Mapping |
---|---|---|
Use an EISDirectMapping
(with XML records), an XMLDirectMapping
or their subclasses to map a Java attribute to an xsd:union
type, such as the following:
<xsd:simpleType name="size-type"> <xsd:union memberTypes="xsd:decimal xsd:string"/> </xsd:simpleType>
When TopLink marshalls (writes) an object to XML, it uses its default conversion pairs to convert from the Java type to the appropriate xsd
type.
In the case where the memberTypes
map to the same Java type, TopLink marshalls using the first memberType
in the union which allows a successful conversion. For example, if you map a Java type of byte[]
to an xsd:union
with memberTypes
of hexBinary
and base64Binary
, then TopLink marshalls using the first memberType
: hexBinary
.
You can customize the default conversion pairs to control the Java type to xsd
type conversion using XMLField
method addConversion
and configuring your mapping with that XMLField
using EISDirectMapping
or XMLDirectMapping
method setField
. For example, if the memberTypes
were xsd:date
and xsd:time
and the Java attribute was of type java.util.Date
instead of the JAXB 1.0 standard java.util.Calendar
, you can modify the conversion pair for xsd:date
to be java.util.Date
.
When TopLink unmarshalls (reads) XML into an object, it tries each memberType
in the order specified in the XSD until the first successful conversion is made.
If your XML document specifies the xsi:type
attribute on an element, then TopLink converts according to the xsi:type
instead of trying the memberTypes
.
For more information, see Section 53.3.5, "Mapping to a Union Field with an XML Direct Mapping". The same applies to an EISDirectMapping
with XML records (see Section 77.3, "EIS Direct Mapping").
You can map a Java attribute to an xsd:list
type, such as:
<xsd:simpleType name="sizes"> <xsd:list itemType="xsd:int"/> </xsd:simpleType>
If you represent the xsd:list
in your object model as a Java List
type, use an EISCompositeDirectCollectionMapping
(with XML records), an XMLCompositeDirectCollectionMapping
or their subclasses and use mapping method useCollectionClass
to specify the List
type of the Java attribute.
If you represent the list in your object model as a String
of white space delimited tokens (for example, "aaa bbb ccc"
), use an EISDirectMapping
(with XML records), an XMLDirectMapping
or their subclasses to map this Java attribute to an xsd:list
(for example, <item>aaa bbb ccc</item>
).
In either case, you can configure whether or not the mapping unmarshalls (writes) the list to a single node, like <item>aaa bbb ccc</item>
, or to multiple nodes, such as the following:
<item>aaa</item> <item>bbb</item> <item>ccc</item>
For more information on mapping to an xsd:list
type using an XMLCompositeDirectCollectionMapping
or its subclasses, see the following:
Section 53.4.3, "Mapping to a Single Text Node with an XML Composite Direct Collection Mapping"
Section 53.4.4, "Mapping to a Single Attribute with an XML Composite Direct Collection Mapping"
The same applies to an EISCompositeDirectCollectionMapping
(with XML records).
For more information about mapping to an xsd:list
type using an XMLDirectMapping
or its subclasses, see Section 53.3.4, "Mapping to a List Field with an XML Direct Mapping". The same applies to an EISDirectMapping
with XML records (see Section 77.3, "EIS Direct Mapping").
Use an EISCompositeDirectCollectionMapping
(with XML records), an XMLCompositeDirectCollectionMapping
or their subclasses to map a Java attribute to an xsd:list
that contains xsd:union
types, such as:
<xsd:element name="listOfUnions" type="listOfUnions"/> <xsd:simpleType name="listOfUnions"> <xsd:list> <xsd:simpleType> <xsd:union memberTypes="xsd:date xsd:integer"/> </xsd:simpleType> </xsd:list> </xsd:simpleType>
When TopLink marshalls (writes) an object to XML, it does not rely on a single xsd:list
itemType
. Instead, for each item in the list, TopLink tries each memberType
until the first successful conversion.
For more information, see Section 53.4.5, "Mapping to a List of Unions with an XML Composite Direct Collection Mapping". The same applies to an EISCompositeDirectCollectionMapping
with XML records (see Section 77.4, "EIS Composite Direct Collection Mapping").
You can map a Java attribute to an xsd:union
type whose memberTypes
are xsd:list
types where each xsd:list
contains items of a single type, such as:
<xsd:element name="listOfUnions" type="UnionOfLists"/> <xsd:simpleType name="UnionOfLists"> <xsd:union memberTypes="xsd:double"> <xsd:simpleType> <xsd:list itemType="xsd:date"/> </xsd:simpleType> <xsd:simpleType> <xsd:list itemType="xsd:integer"/> </xsd:simpleType> </xsd:union> </xsd:simpleType>
Note that in this example, valid XML documents contain either all xsd:double
, all xsd:date
, or all xsd:integer
values.
If you represent the list in your object model as a String
of white space delimited tokens (for example, "aaa bbb ccc"
), use an EISDirectMapping
(with XML records) or an XMLDirectMappng
to map this Java attribute to an xsd:list
(for example, <item>aaa bbb ccc</item>
).
If you represent the list in your object model as a Java List
type, use an EISCompositeDirectCollectionMapping
(with XML records), an XMLCompositeDirectCollectionMapping
or their subclasses.
For more information, see the following:
Section 53.3.6, "Mapping to a Union of Lists with an XML Direct Mapping". The same applies to an EISDirectMapping
with XML records (see Section 77.3, "EIS Direct Mapping").
Section 53.4.6, "Mapping to a Union of Lists with an XML Composite Direct Collection Mapping". The same applies to an EISCompositeDirectCollectionMapping
with XML records (see Section 77.4, "EIS Composite Direct Collection Mapping").
Use an EISDirectMapping
(with XML records), an XMLDirectMapping
or their subclasses to map a Java attribute to an xsd:union
that contains xsd:union
types, such as the following:
<xsd:simpleType name="UnionOfUnions"> <xsd:union> <xsd:simpleType> <xsd:union> <xsd:simpleType> <xsd:list itemType="xsd:date"/> </xsd:simpleType> <xsd:simpleType> <xsd:list itemType="xsd:integer"/> </xsd:simpleType> </xsd:union> </xsd:simpleType> <xsd:simpleType> <xsd:union> <xsd:simpleType> <xsd:list itemType="xsd:string"/> </xsd:simpleType> <xsd:simpleType> <xsd:list itemType="xsd:float"/> </xsd:simpleType> </xsd:union> </xsd:simpleType> </xsd:union> </xsd:simpleType>
Note that in this example, valid XML documents may contain any of xsd:date
, xsd:integer
, xsd:string
, or xsd:float
.
For more information, see Section 53.3.7, "Mapping to a Union of Unions with an XML Direct Mapping". The same applies to an EISDirectMapping
with XML records (see Section 77.3, "EIS Direct Mapping").
Using the jaxb:class
customization, you can declaratively specify an application-specific subclass of a schema-derived implementation class. This lets you write your own classes that extend JAXB's generated implementation classes (see Section 47.1.1.2.1, "Implementation Classes"). The JAXB runtime binding framework can then access your subclasses.
When you create an EIS composite object mapping to XML records, or an XML composite object mapping to XML documents, you can configure the mapping's XPath (Section 121.4, "Configuring XPath") to accommodate jaxb:class
customizations with the following XSD structures:
When mapping to jaxb:class
customized structures, consider the limitations of TopLink support for this customization (see Section 17.2.9.6, "Limitations of jaxb:class Customization Support").
You can use the jaxb:class
customization with an all
, choice
, or sequence
structure. Example 17-1 shows a jaxb:class
customization of an all
structure.
Example 17-1 jaxb:class Customization of an all Structure
<xsd:element name="employee"> <xsd:complexType> <xsd:all> <xsd:annotation> <xsd:appinfo> <jaxb:class name="period"/> </xsd:appinfo> </xsd:annotation> <xsd:element name="startDate" type="xsd:date"/> <xsd:element name="endDate" type="xsd:date"/> </xsd:all> </xsd:complexType> </xsd:element>
This directs the JAXB compiler to create an inner class named Period
in the owning element's class for the all
structure. Use an EISCompositeObjectMapping
(with XML records) or an XMLCompositeObjectMapping
to map a Java attribute to this inner class.
For more information, see Section 53.5, "XML Composite Object Mapping". The same applies to an EISCompositeObjectMapping
with XML records (see Section 77.5, "EIS Composite Object Mapping").
You can use the jaxb:class
customization with a group
structure, as Example 17-2 shows.
Example 17-2 jaxb:class Customization of a group Structure
<xsd:group name="G1"> <xsd:annotation> <xsd:appinfo> <jaxb:class name="period"/> </xsd:appinfo> </xsd:annotation> <xsd:sequence> <xsd:element name="startDate" type="xsd:date"/> <xsd:element name="endDate" type="xsd:date"/> </xsd:sequence> </xsd:group> <xsd:element name="employee"> <xsd:complexType> <xsd:group ref="G1"/> </xsd:complexType> </xsd:element>
This directs the JAXB compiler to create an external wrapper class named Period
for the group
structure. Use an EISCompositeObjectMapping
(with XML records) or an XMLCompositeObjectMapping
to map a Java attribute to this external wrapper class.
For more information, see Section 53.5, "XML Composite Object Mapping". The same applies to an EISCompositeObjectMapping
with XML records (see Section 77.5, "EIS Composite Object Mapping").
You can use the jaxb:class
customization with a sequence
or choice
structure that contains a group
. Example 17-3 shows a jaxb:class
customization of a sequence
structure containing a group
structure.
Example 17-3 jaxb:class Customization of a sequence Structure Containing a group
<xsd:element name="employee"> <xsd:complexType> <xsd:sequence> <xsd:annotation> <xsd:appinfo> <jaxb:class name="EmploymentInfo"/> </xsd:appinfo> </xsd:annotation> <xsd:element name="id" type="xsd:int"/> <xsd:group ref="G1"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:group name="G1"> <xsd:annotation> <xsd:appinfo> <jaxb:class name="Period"/> </xsd:appinfo> </xsd:annotation> <xsd:sequence> <xsd:element name="startDate" type="xsd:date"/> <xsd:element name="endDate" type="xsd:date"/> </xsd:sequence> </xsd:group>
This directs the JAXB compiler to create an inner class named EmploymentInfo
in the owning element's class for the sequence
structure and an external wrapper class named Period
for the group
structure. The inner class references the external wrapper class. Use an EISCompositeObjectMapping
(with XML records) or an XMLCompositeObjectMapping
to map a Java attribute to this inner class.
For more information, see Section 53.5, "XML Composite Object Mapping". The same applies to an EISCompositeObjectMapping
with XML records (see Section 77.5, "EIS Composite Object Mapping".
You can use the jaxb:class
customization with a group
structure that contains a sequence
or choice
. Example 17-4 shows a jaxb:class
customization of a group
structure containing a sequence
structure.
Example 17-4 jaxb:class Customization of a group Structure Containing a sequence
<xsd:group name="G1"> <xsd:annotation> <xsd:appinfo> <jaxb:class name="EmploymentInfo"/> </xsd:appinfo> </xsd:annotation> <xsd:sequence> <xsd:annotation> <xsd:appinfo> <jaxb:class name="Period"/> </xsd:appinfo> </xsd:annotation> <xsd:element name="startDate" type="xsd:date"/> <xsd:element name="endDate" type="xsd:date"/> </xsd:sequence> </xsd:group> <xsd:element name="employee"> <xsd:complexType> <xsd:sequence> <xsd:element name="id" type="xsd:int"/> <xsd:group ref="G1"/> </xsd:sequence> </xsd:complexType> </xsd:element>
This directs the JAXB compiler to create an external wrapper class named EmploymentInfo
for the group
structure and an inner class named Period
in the external wrapper class for the sequence
structure. The owning element references the external wrapper class. Use an EISCompositeObjectMapping
(with XML records) or an XMLCompositeObjectMapping
to map a Java attribute to this external wrapper class.
For more information, see Section 53.5, "XML Composite Object Mapping". The same applies to an EISCompositeObjectMapping
with XML records (see Section 77.5, "EIS Composite Object Mapping").
You can use the jaxb:class
customization with a group
structure that contains another group
structure, as Example 17-5 shows.
Example 17-5 jaxb:class Customization of a group Structure Containing a group
<xsd:group name="G1"> <xsd:annotation> <xsd:appinfo> <jaxb:class name="EmploymentInfo"/> </xsd:appinfo> </xsd:annotation> <xsd:sequence> <xsd:element name="id" type="xsd:int"/> <xsd:group ref="G2"/> </xsd:sequence> </xsd:group> <xsd:group name="G2"> <xsd:annotation> <xsd:appinfo> <jaxb:class name="Period"/> </xsd:appinfo> </xsd:annotation> <xsd:sequence> <xsd:element name="startDate" type="xsd:date"/> <xsd:element name="endDate" type="xsd:date"/> </xsd:sequence> </xsd:group> <xsd:element name="employee"> <xsd:complexType> <xsd:group ref="G1"/> </xsd:complexType> </xsd:element>
This directs the JAXB compiler to create a wrapper class named EmploymentInfo
for the group
structure that the owning element's class references and another wrapper class named Period
for the group
structure that the EmploymentInfo
class references. Use an EISCompositeObjectMapping
(with XML records) or an XMLCompositeObjectMapping
to map a Java attribute to these wrapper classes.
For more information, see Section 53.5, "XML Composite Object Mapping". The same applies to an EISCompositeObjectMapping
with XML records (see Section 77.5, "EIS Composite Object Mapping").
When mapping to jaxb:class customized structures, consider the following limitations:
Unbounded structures are not supported.
Partial validation is not supported.
When mapping sequence elements to a composite object, the XML schema must order the elements so that the elements you map to the composite object are kept together.
The sequence
structure forces all elements to occur in the order in which they are specified in the XML schema. Consider the XML schema shown in Example 17-6. A valid XML instance must contain the sequence elements in the specified order:
street
, customerName
, city
In this example, you want to map the customerName
attribute with a direct mapping and you want to map the street
and city
attributes to a composite Address
object. Depending on the order in which you define the mappings, TopLink will marshall invalid XML document instances in the order
customerName
, street
, city
or
street
, city
, customerName
.
Example 17-6 XML Schema With Unsupported Sequence Element Order
<xs:element name="customer"> <xs:complexType> <xs:sequence> <xs:element name="street" type="xs:string"/> <xs:element name="customerName" type="xs:string" /> <xs:element name="city" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element>
To correct this problem, modify the XML schema to keep the elements you want to map to the composite object together (see Example 17-7) and define the mappings in the order specified by the XML schema.
Example 17-7 XML Schema With Supported Sequence Element Order
<xs:element name="customer"> <xs:complexType> <xs:sequence> <xs:element name="customerName" type="xs:string"/> <xs:element name="street" type="xs:string"/> <xs:element name="city" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element>
JAXB binds a typesafe enumeration class to a named simple type definition with a basetype
that derives from xsd:NCName
and has enumeration
facets (see Example 17-8).
Example 17-8 Schema Fragment with Typesafe Enumeration Declaration
<simpleType name="NISTSchema-NCName-enumeration-1-Type"> <restriction base="NCName"> <enumeration value="qbandwidth-and.software-use.too"/> <enumeration value="_effort-disseminate_and-devices.com"/> </restriction> </simpleType>
You can map a Java attribute to such an enumeration using the JAXBTypesafeEnumConverter
with an EISDirectMapping
or EISCompositeDirectCollectionMapping
with XML records, or with an XMLDirectMapping
, XMLCompositeDirectCollectionMapping
or their subclasses with XML documents.
Oracle JDeveloper TopLink Editor and TopLink Workbench do not support the JAXBTypesafeEnumConverter
directly: to configure a mapping with this converter, you must use a descriptor amendment method (see Section 121.13, "Configuring a JAXB Typesafe Enumeration Converter").
If you create a project and object model using the TopLink JAXB compiler (see Section 48.2, "Creating an XML Project from an XML Schema"), the compiler will create the type safe enumeration class and a class with descriptor amendment methods and register the required amendment methods automatically.
All the mapping classes are derived from the DatabaseMapping
class.
Table 17-5 Platform and Mapping Package Compatibility
Platform | Mapping Package |
---|---|
For relational projects |
|
For EIS projects |
|
For XML projects |
|
A relational mapping transforms any object data member type to a corresponding relational database (SQL) data source representation in any supported relational database. Relational mappings allow you to map an object model into a relational data-model.
Relational mappings can also transform object data members that reference other domain objects that are stored in other tables in the database and are related through foreign keys.
Use relational mappings in relational projects. For more information, see Section 18.1, "Building Relational Projects".
For more information about relational mappings, see Part XII, "Relational Mappings"
An object-relational data type mapping transforms certain object data member types to structured data source representations optimized for storage in specialized object-relational data type databases such as Oracle Database. Object-relational data type mappings allow you to map an object model into an object-relational data type data-model.
Use object-relational data type mappings in relational projects. For more information, see Section 18.1, "Building Relational Projects".
For more information about object-relational data type mappings, see Part XIII, "Object-Relational Data Type Mappings".
An XML mapping transforms object data members to the XML elements of an XML file whose structure is defined by an XML schema document (XSD).
Use XML mappings in XML projects. For more information, see Section 47.1, "XML Project Concepts".
For more information about XML mappings, see Part XVI, "XML Mappings".
An EIS mapping transforms object data members to the EIS record format defined by the object's descriptor.
Use EIS mappings in EIS projects. For more information, see Section 71.1, "EIS Project Concepts".
For more information about EIS mappings, see Part XIX, "EIS Mappings".