Chapter 7. Mapping

7.1. Forward Mapping
7.1.1. Using the Mapping Tool
7.1.2. Generating DDL SQL
7.1.3. JDO Forward Mapping Hints
7.1.4. Runtime Forward Mapping
7.2. Reverse Mapping
7.2.1. Customizing Reverse Mapping
7.3. Meet-in-the-Middle Mapping
7.4. Mapping Defaults
7.5. Mapping Factory
7.5.1. Importing and Exporting Mapping Data
7.6. Non-Standard Joins
7.7. Additional JPA Mappings
7.7.1. Datastore Identity Mapping
7.7.2. Surrogate Version Mapping
7.7.3. Multi-Column Mappings
7.7.4. Join Column Attribute Targets
7.7.5. Embedded Mapping
7.7.6. Collections
7.7.6.1. Container Table
7.7.6.2. Element Columns
7.7.6.3. Element Join Columns
7.7.6.4. Element Embedded Mapping
7.7.6.5. Order Column
7.7.6.6. Examples
7.7.7. One-Sided One-Many Mapping
7.7.8. Maps
7.7.8.1. Key Columns
7.7.8.2. Key Join Columns
7.7.8.3. Key Embedded Mapping
7.7.8.4. Examples
7.7.9. Indexes and Constraints
7.7.9.1. Indexes
7.7.9.2. Foreign Keys
7.7.9.3. Unique Constraints
7.7.9.4. Examples
7.8. Mapping Limitations
7.8.1. Table Per Class
7.9. Mapping Extensions
7.9.1. Class Extensions
7.9.1.1. Subclass Fetch Mode
7.9.1.2. Strategy
7.9.1.3. Discriminator Strategy
7.9.1.4. Version Strategy
7.9.2. Field Extensions
7.9.2.1. Eager Fetch Mode
7.9.2.2. Nonpolymorphic
7.9.2.3. Class Criteria
7.9.2.4. Strategy
7.9.3. Column Extensions
7.9.3.1. insertable
7.9.3.2. updatable
7.9.3.3. lock-group
7.10. Custom Mappings
7.10.1. Custom Class Mapping
7.10.2. Custom Discriminator and Version Strategies
7.10.3. Custom Field Mapping
7.10.3.1. Value Handlers
7.10.3.2. Field Strategies
7.10.3.3. Configuration
7.11. Orphaned Keys

The JPA Overview's Chapter 12, Mapping Metadata explains mapping under JPA. The JDO Overview's Chapter 15, Mapping Metadata explains object-relational mapping under JDO. This chapter reviews the mapping utilities Kodo provides and examines Kodo features that go beyond the specifications.

7.1. Forward Mapping

Forward mapping is the process of creating mappings and their corresponding database schema from your object model. Kodo supports forward mapping through the mapping tool. The next section presents several common mapping tool use cases. You can invoke the tool through the mappingtool shell/batch script included in the Kodo distribution, or through its Java class, kodo.jdbc.meta.MappingTool.

[Note]Note

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

Example 7.1. Using the Mapping Tool

mappingtool Magazine.java
mappingtool *.jdo

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

  • -file/-f <stdout | output file>: Use this option to write the planned mappings to an XML document rather than recording them as the mappings for the given classes. This option also specifies the metadata file to write to when using the mapping tool to generate default persistence metadata (see Section 6.1, “Generating Default JDO Metadata”), or the file to dump to if using the export action.

  • -schemaAction/-sa <add | refresh | drop | build | retain | none>: The action to take on the schema. These options correspond to the same-named actions on the schema tool described in Section 4.14, “Schema Tool”. 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.

  • -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.

  • -kodoTables/-kt <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 Kodo 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:

  • refresh: This is the default action when using JDO mapping defaults (see Section 7.4, “Mapping Defaults”). It brings your mappings up-to-date with the class definitions. Kodo will attempt to use any provided mapping information, and fill in missing information. If the provided mappings conflict with a class definition, the conflicting mappings will be discarded and the class or field will be re-mapped to a new column or table.

  • add: If used with the -meta option, adds new default metadata for the given classes. Otherwise, brings your mappings up-to-date with the class definitions. Kodo will attempt to use any provided mapping information, and fill in missing information. If the provided mappings conflict with a class definition, Kodo will fail with an informative exception.

  • buildSchema: This is the default action when using JPA mapping defaults (see Section 7.4, “Mapping Defaults”). It makes the database schema match your existing mappings. If your provided mappings conflict with a class definition, Kodo will fail with an informative exception.

  • drop: Delete the mappings for the given classes. If used with the -meta option, also deletes persistence metadata

  • 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.

  • import: Import mappings from the given XML document and store them as the current system mappings. Under this action, the mapping tool expects its arguments to be XML files in the orm mapping format described in Chapter 15, Mapping Metadata of the JDO Overview, rather than persistent classes.

  • export: Export the mapping data for the given classes to an XML file in the orm mapping format described in Chapter 15, Mapping Metadata of the JDO Overview.

[Note]Note

When using JPA annotation mappings, you cannot run the refresh, add, or drop mapping tool actions. Each of these actions changes existing mappings, and Kodo cannot yet write your annotations for you.

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.

  • A .jdo metadata file. The tool will run on each class listed in the metadata.

  • A .orm mapping file. The tool will run on each class listed in the mapping metadata. If you are running the import action, each argument must be a .orm file.

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

If you have not specified a persistent class list, the tool will scan your classpath for directories containing .jdo files, and run on all classes listed in those files.

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

7.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 12, Mapping Metadata of the JPA Overview to override any unsatisfactory defaults, run the mapping tool's buildSchema action on your persistent classes. This is the default action when you use JPA mapping defaults (see Section 7.4, “Mapping Defaults”).

The buildSchema 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

JPA mapping defaults:

mappingtool Magazine.java

JDO mapping defaults:

mappingtool -a buildSchema package.jdo

In standard forward mapping under JDO, you concentrate your efforts on your object model, and the mapping tool's refresh action keeps your mappings and schema up-to-date. The refresh action examines both the existing database schema and any existing mappings. Classes and fields that are not mapped, or whose mapping information no longer matches the object model, are automatically given new mappings. The tool also updates the schema as necessary to support both existing mappings and any new mappings it creates. The example below shows how to invoke the refresh action on the mapping tool to create or update the mapping information and database schema for the persistent classes listed in package.jdo.

Example 7.3. Refreshing Mappings and the Relational Schema

mappingtool package.jdo

You can safely run the refresh action on classes that have already been mapped, because the tool only generates new mappings when the old ones have become incompatible with the class. If the tool does have to replace a bad mapping, it does not modify other still-valid mappings. For example, if you change the type of a field from int to String, the mapping tool will detect the incompatibility with the old numeric column, add a new string-compatible column to the class' database table, and change the field's mapping data to point to the new column. All other fields will retain their original mappings.

In fact, if you want to make sure the mapping tool does not alter any of your existing mappings, you can use the add action in place of the default refresh action. When the mapping tool encounters what it thinks is a bad mapping under the add action, it throws an informative exception rather than replacing the mapping. This is particularly useful if you write mappings by hand, but want the tool to create the corresponding schema for you.

Example 7.4. Adding Mappings and the Relational Schema

mappingtool -a add package.jdo

To drop JDO mapping data, use the drop action. This action does not affect the schema.

Example 7.5. Dropping Mappings

mappingtool -a drop package.jdo

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

Example 7.6. Dropping Mappings and Association Schema

mappingtool -sa drop Magazine.java
mappingtool -sa drop package.jdo

7.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.7. 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.

mappingtool -a buildSchema -sa build -sql create.sql Magazine.java

Example 7.8. 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.

mappingtool -a buildSchema -sql update.sql Magazine.java

Example 7.9. Refresh JDO Mappings and Create DDL

This example refreshes the mappings for the classes in package.jdo and writes all the SQL necessary to recreate the tables used by these mappings to create.sql.

mappingtool -sa build -sql create.sql package.jdo

Example 7.10. Refresh JDO Mappings and Create DDL to Update Database

This example refreshes the mappings for the classes in package.jdo. It writes the SQL to add tables or columns missing from the current schema to the update.sql file.

mappingtool -sql update.sql package.jdo

7.1.3.  JDO Forward Mapping Hints

Forward mapping in Kodo JDO is not an all-or-nothing endeavor. Kodo allows you to specify bits and pieces of mapping information; the mapping tool will fill in the rest. For example, if you want the column for your Magazine.isbn field to be type CHAR(15), or you want to use the new-table inheritance strategy to create a joined subclass table, you can specify these pieces of information without filling in column names, table names, and other data whose defaults are satisfactory.

Example 7.11. Partial Mapping

<class name="Magazine">
    <field name="isbn">
        <column jdbc-type="char" length="15"/>
    </field>
    ...
</class>
<class name="FullTimeEmployee">  <!-- extends Employee -->
    <inheritance strategy="new-table"><join/></inheritance>
    ...
</class>
[Important]Important

In the FullTimeEmployee example above, the join within the inheritance element is very important. Recall that the join element is all that separates a joined inheritance mapping from a table-per-class mapping. Thus, specifying a new-table subclass strategy without using a join element hint will cause Kodo to create an unjoined table-per-class mapping instead of a joined mapping.

The mapping tool will incorporate your partial mapping hints into the full mappings it creates. The tool even allows you to specify the hints in your .jdo file when your mappings are stored somewhere else, such as separate .orm files. This allows you to integrate mapping hints into the metadata for unmapped classes or newly-added fields without having to write a separate mapping file. This also brings up a potential conflict, however: when you have mapping information in both your .jdo file and the configured mapping format such as a .orm file, which takes precedence during tool runs? The answer is that the data in the configured mapping format always wins, just as it does at runtime. Mapping hints only work for classes or fields that have not yet been mapped. If you have configured Kodo to store mappings in .orm files, the mapping tool will ignore mapping hints for any class or field already mentioned in your .orm mapping information.

In addition to hinting through partial mapping, the mapping tool recognizes some general directives communicated through mapping metadata:

  • When mapping an embedded relation, you can set the embedded element's null-indicator-column attribute to true to have Kodo create a synthetic null indicator column with a default name. You can also set this attribute to the name of a field in the embedded class. Kodo will use that field's column as the null indicator column. Of course, Kodo also allows you to specify a column name directly, as the attribute intends.

  • You can set the column attribute of the order element to true or false to force or suppress the creation of an ordering column for a collection field.

7.1.4. Runtime Forward Mapping

You can configure Kodo to automatically run the mapping tool at runtime through the kodo.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 5.1, “Persistent Class List”.

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

The kodo.jdbc.SynchronizeMappings property is a plugin string (see Section 2.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.12. Configuring Runtime Forward Mapping

JPA XML format:

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

JDO properties format:

kodo.jdbc.SynchronizeMappings: buildSchema(ForeignKeys=true)

The setting above corresponds to running the following command:

mappingtool -a buildSchema -fk true

 

Skip navigation bar   Back to Top