Understanding EclipseLink, 2.4
  Go To Table Of Contents
 Search
 PDF

Common Mapping Concepts

This section describes concepts for relational and nonrelational mappings that are unique to EclipseLink:

Mapping Architecture

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.


NoteNote:

A mapping is the same regardless of whether your project is persistent or nonpersistent.


For an example of a typical EclipseLink mapping, see Mapping Examples.

The type of data source you define in your 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).

A descriptor represents a particular domain object: it describes the object's class. A descriptor also owns the mappings: one mapping for each of the class data members that you intend to persist or transform in memory.

For more information about descriptors, see Chapter 6, "Understanding Descriptors".

Mapping Examples

Although EclipseLink supports more complex mappings, most EclipseLink 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 7-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 7-1 How Classes and Objects Map to a Database Table

Description of Figure 7-1 follows
Description of "Figure 7-1 How Classes and Objects Map to a Database Table"

EclipseLink provides you with the tools to build these mappings, from the simple mappings illustrated in Figure 7-1, to complex mappings.

For an additional example of a relational mapping, see Figure 7-2, "Serialized Object Converter (relational)".

Using Lazy Loading

JPA specifies that lazy loading is a hint to the persistence provider that data should be fetched lazily when it is first accessed, if possible. If you are developing your application in a Java EE environment, set fetch to javax.persistence.FetchType.LAZY, and the persistence provider supplies all the necessary functionality.

When using a one-to-one or many-to-one mapping in a Java SE environment, use either dynamic or static weaving to perform lazy loading when the fetch attribute is set to FetchType.LAZY.

When using a one-to-one or many-to-one mapping in a Java SE environment and the environment does not permit the use of -javaagent on the JVM command line, use static weaving to perform lazy loading when the fetch attribute is set to FetchType.LAZY.

Table 7-1 lists support for lazy loading by mapping type.

Table 7-1 Support for Lazy Loading by Mapping Type

Mapping Java EE Java SE

Many-to-many

Lazy loading is performed when the fetch attribute is set to javax.persistence.FetchType.LAZY (default).

Lazy loading is performed when the fetch attribute is set to javax.persistence.FetchType.LAZY (default).

One-to-many

Lazy loading is performed when the fetch attribute is set to javax.persistence.FetchType.LAZY (default).

Lazy loading is performed when the fetch attribute is set to javax.persistence.FetchType.LAZY (default).

One-to-one

Lazy loading is performed when the fetch attribute is set to javax.persistence.FetchType.LAZY.

The fetch attribute is ignored and default javax.persistence.FetchType.EAGER applies.

Many-to-one

Lazy loading is performed when the fetch attribute is set to javax.persistence.FetchType.LAZY.

The fetch attribute is ignored and default javax.persistence.FetchType.EAGER applies

Basic

Lazy loading is performed when the fetch attribute is set to javax.persistence.FetchType.LAZY.

The fetch attribute is ignored and default javax.persistence.FetchType.EAGER applies


Mapping Converters and Transformers

If existing EclipseLink mappings do not meet your needs, you can create custom mappings using mapping extensions. These extensions include the following:


NoteNote:

Except for simple type translation, you can use the mapping converters and transformers regardless of whether your data source is relational or nonrelational. Simple type translation is applicable only to XML projects.


Serialized Object Converter

The serialized object converter can be used with direct and direct collection mappings, allowing you to 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 7-2 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 7-2 Serialized Object Converter (relational)

Description of Figure 7-2 follows
Description of "Figure 7-2 Serialized Object Converter (relational)"

Figure 7-3 demonstrates an example of a nonrelational mapping that uses a serialized object converter. The attribute jobDescription contains a formatted text document that EclipseLink stores in the JOB DESCRIPTION element of an XML schema.

Figure 7-3 Serialized Object Converter (nonrelational)

Description of Figure 7-3 follows
Description of "Figure 7-3 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.

Type Conversion Converter

The type conversion converter can be used with direct and direct collection mappings, allowing you to map complex objects into binary fields. 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 7-4 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 7-4 Type Conversion Mapping (relational)

Description of Figure 7-4 follows
Description of "Figure 7-4 Type Conversion Mapping (relational) "

Figure 7-5 illustrates a type conversion mapping (nonrelational). java.util.Date object is mapped to a String in a XML schema.

Figure 7-5 Type Conversion Mapping (nonrelational)

Description of Figure 7-5 follows
Description of "Figure 7-5 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.

EclipseLink uses the NCharacter, NClob and NString types in the org.eclipse.persistence.platform.database.oracle package as the converter data type to support the NCHAR, NCLOB and NVARCHAR2 types. EclipseLink 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 Transformation Mappings).

Object Type Converter

The object type converter can be used with direct and direct collection mappings allowing you to match a fixed number of values to Java objects. Use this converter when the values in the schema differ from those in Java.

Figure 7-6 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, EclipseLink stores it in the XML element as F.

Figure 7-6 Object Type XML Converter

Description of Figure 7-6 follows
Description of "Figure 7-6 Object Type XML Converter"

Transformation Mappings

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: performs the object attribute transformation at read time

  • field transformer: performs the object attribute-to-field transformation at write 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 Transformation Mapping.

Transformation Mapping

Use transformation mappings for specialized translations for how a value is represented in Java and how it is represented in the database.


Tip:

Because of the complexity of transformation mappings, it is often easier to perform the transformation with a converter or getter and setter methods of a direct-to-field mapping.


Figure 7-7 illustrates a transformation mapping. The values from the B_DATE and B_TIME fields are used to create a java.util.Date to be stored in the birthDate attribute.

Figure 7-7 Transformation Mappings

Description of Figure 7-7 follows
Description of "Figure 7-7 Transformation Mappings"

Often, a transformation mapping is appropriate when values from multiple fields are used to create an object. This type of mapping requires that you provide an attribute transformation that is invoked when reading the object from the database. This must have at least one parameter that is an instance of Record. In your attribute transformation, you can use Record method get to retrieve the value in a specific column. Your attribute transformation can optionally specify a second parameter, an instance of Session. The Session performs queries on the database to get additional values needed in the transformation. The transformation should return the value to be stored in the attribute.

Transformation mappings also require a field transformation for each field, to be written to the database when the object is saved. The transformation returns the value to be stored in that field.