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.

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.

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

-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

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

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.

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.