Chapter 7.  Mapping

Table of Contents

1. Forward Mapping
1.1. Using the Mapping Tool
1.2. Generating DDL SQL
1.3. Runtime Forward Mapping
2. Reverse Mapping
2.1. Customizing Reverse Mapping
3. Meet-in-the-Middle Mapping
4. Mapping Defaults
5. Mapping Factory
6. Non-Standard Joins
7. Additional JPA Mappings
7.1. Datastore Identity Mapping
7.2. Surrogate Version Mapping
7.3. Multi-Column Mappings
7.4. Join Column Attribute Targets
7.5. Embedded Mapping
7.6. Collections
7.6.1. Container Table
7.6.2. Element Join Columns
7.6.3. Order Column
7.7. One-Sided One-Many Mapping
7.8. Maps
7.8.1. Key Columns
7.8.2. Key Join Columns
7.8.3. Key Embedded Mapping
7.8.4. Examples
7.9. Indexes and Constraints
7.9.1. Indexes
7.9.2. Foreign Keys
7.9.3. Unique Constraints
7.10. XML Column Mapping
7.11. LOB Streaming
8. Mapping Limitations
8.1. Table Per Class
9. Mapping Extensions
9.1. Class Extensions
9.1.1. Subclass Fetch Mode
9.1.2. Strategy
9.1.3. Discriminator Strategy
9.1.4. Version Strategy
9.2. Field Extensions
9.2.1. Eager Fetch Mode
9.2.2. Nonpolymorphic
9.2.3. Class Criteria
9.2.4. Strategy
10. Custom Mappings
10.1. Custom Class Mapping
10.2. Custom Discriminator and Version Strategies
10.3. Custom Field Mapping
10.3.1. Value Handlers
10.3.2. Field Strategies
10.3.3. Configuration
11. Orphaned Keys

The JPA Overview's Chapter 13, Mapping Metadata explains object-relational mapping under JPA. This chapter reviews the mapping utilities OpenJPA provides and examines OpenJPA features that go beyond the JPA specification.

1.  Forward Mapping

Forward mapping is the process of creating mappings and their corresponding database schema from your object model. OpenJPA supports forward mapping through the mapping tool. The next section presents several common mapping tool use cases. You can invoke the tool through its Java class, org.apache.openjpa.jdbc.meta.MappingTool.

Note

Section 1.4, “ Mapping Tool Ant Task ” describes the mapping tool Ant task.

Example 7.1.  Using the Mapping Tool

java org.apache.openjpa.jdbc.meta.MappingTool Magazine.java

In addition to the universal flags of the configuration framework, the mapping tool accepts the following command line arguments:

  • -schemaAction/-sa <add | refresh | drop | build | retain | reflect | createDB | dropDB | import | export | none> : The action to take on the schema. These options correspond to the same-named actions on the schema tool described in Section 13, “ Schema Tool ”. Actions can be composed in a comma-separated list. Unless you are running the mapping tool on all of your persistent types at once or dropping a mapping, we strongly recommend you use the default add action or the build action. Otherwise you may end up inadvertently dropping schema components that are used by classes you are not currently running the tool over.

  • -schemaFile/-sf <stdout | output file>: Use this option to write the planned schema to an XML document rather than modify the database. The document can then be manipulated and committed to the database with the schema tool.

  • -sqlFile/-sql <stdout | output file>: Use this option to write the planned schema modifications to a SQL script rather than modify the database. Combine this with a schemaAction of build to generate a script that recreates the schema for the current mappings, even if the schema already exists.

  • -sqlEncode/-se <encoding>: Use this option with -sqlFile to write the SQL script in a different Java character set encoding than the default JVM locale, such as UTF-8.

  • -dropTables/-dt <true/t | false/f>: Corresponds to the same-named option on the schema tool.

  • -dropSequences/-dsq <true/t | false/f>: Corresponds to the same-named option on the schema tool.

  • -openjpaTables/-ot <true/t | false/f>: Corresponds to the same-named option on the schema tool.

  • -ignoreErrors/-i <true/t | false/f>: Corresponds to the same-named option on the schema tool.

  • -schemas/-s <schema and table names>: Corresponds to the same-named option on the schema tool. This option is ignored if readSchema is not set to true.

  • -readSchema/-rs <true/t | false/f>: Set this option to true to read the entire existing schema when the tool runs. Reading the existing schema ensures that OpenJPA does not generate any mappings that use table, index, primary key, or foreign key names that conflict with existing names. Depending on the JDBC driver, though, it can be a slow process for large schemas.

  • -primaryKeys/-pk <true/t | false/f>: Whether to read and manipulate primary key information of existing tables. Defaults to false.

  • -foreignKeys/-fk <true/t | false/f>: Whether to read and manipulate foreign key information of existing tables. Defaults to false. This means that to add any new foreign keys to a class that has already been mapped, you must explicitly set this flag to true.

  • -indexes/-ix <true/t | false/f>: Whether to read and manipulate index information of existing tables. Defaults to false. This means that to add any new indexes to a class that has already been mapped once, you must explicitly set this flag to true.

  • -sequences/-sq <true/t | false/f>: Whether to manipulate sequences. Defaults to true.

  • -meta/-m <true/t | false/f>: Whether the given action applies to metadata rather than or in addition to mappings.

The mapping tool also uses an -action/-a argument to specify the action to take on each class. The available actions are:

  • buildSchema: This is the default action. It makes the database schema match your existing mappings. If your provided mappings conflict with your class definitions, OpenJPA will fail with an informative exception.

  • validate: Ensure that the mappings for the given classes are valid and that they match the schema. No mappings or tables will be changed. An exception is thrown if any mappings are invalid.

Each additional argument to the tool should be one of:

  • The full name of a persistent class.

  • The .java file for a persistent class.

  • The .class file of a persistent class.

If you do not supply any arguments to the mapping tool, it will run on the classes in your persistent classes list (see Section 1, “ Persistent Class List ”).

The mappings generated by the mapping tool are stored by the system mapping factory. Section 5, “ Mapping Factory ” discusses your mapping factory options.

1.1.  Using the Mapping Tool

The JPA specification defines a comprehensive set of defaults for missing mapping information. Thus, forward mapping in JPA is virtually automatic. After using the mapping annotations covered in Chapter 13, Mapping Metadata of the JPA Overview to override any unsatisfactory defaults, run the mapping tool on your persistent classes. The default buildSchema mapping tool action manipulates the database schema to match your mappings. It fails if any of your mappings don't match your object model.

Example 7.2.  Creating the Relational Schema from Mappings

java org.apache.openjpa.jdbc.meta.MappingTool Magazine.java

To drop the schema for a persistent class, set the mapping tool's schemaAction to drop.

Example 7.3.  Refreshing entire schema and cleaning out tables

java org.apache.openjpa.jdbc.meta.MappingTool -schemaAction add,deleteTableContents

Example 7.4.  Dropping Mappings and Association Schema

java org.apache.openjpa.jdbc.meta.MappingTool -schemaAction drop Magazine.java

1.2.  Generating DDL SQL

The examples below show how to use the mapping tool to generate DDL SQL scripts, rather than modifying the database directly.

Example 7.5.  Create DDL for Current Mappings

This example uses your existing mappings to determine the needed schema, then writes the SQL to create that schema to create.sql.

java org.apache.openjpa.jdbc.meta.MappingTool -schemaAction build -sql create.sql Magazine.java

Example 7.6.  Create DDL to Update Database for Current Mappings

This example uses your existing mappings to determine the needed schema. It then writes the SQL to add any missing tables and columns to the current schema to update.sql.

java org.apache.openjpa.jdbc.meta.MappingTool -sql update.sql Magazine.java

1.3.  Runtime Forward Mapping

You can configure OpenJPA to automatically run the mapping tool at runtime through the openjpa.jdbc.SynchronizeMappings configuration property. Using this property saves you the trouble of running the mapping tool manually, and is meant for use during rapid test/debug cycles.

In order to enable automatic runtime mapping, you must first list all your persistent classes as described in Section 1, “ Persistent Class List ”.

OpenJPA will run the mapping tool on these classes when your application obtains its first EntityManager.

The openjpa.jdbc.SynchronizeMappings property is a plugin string (see Section 4, “ Plugin Configuration ”) where the class name is the mapping tool action to invoke, and the properties are the MappingTool class' JavaBean properties. These properties correspond go the long versions of the tool's command line flags.

Example 7.7.  Configuring Runtime Forward Mapping

<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>

The setting above corresponds to running the following command:

java org.apache.openjpa.jdbc.meta.MappingTool -action buildSchema -foreignKeys true