blob: 24c9b43c62d44e162f2c4b3c80c1f078ca3a92cc [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>2.&nbsp; Reverse Mapping</title><base href="display"><link rel="stylesheet" type="text/css" href="css/docbook.css"><meta name="generator" content="DocBook XSL-NS Stylesheets V1.76.1"><link rel="home" href="manual.html" title="Apache OpenJPA 2.3 User's Guide"><link rel="up" href="ref_guide_mapping.html" title="Chapter&nbsp;7.&nbsp; Mapping"><link rel="prev" href="ref_guide_mapping.html" title="Chapter&nbsp;7.&nbsp; Mapping"><link rel="next" href="ref_guide_mapping_middle.html" title="3.&nbsp; Meet-in-the-Middle Mapping"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">2.&nbsp;
Reverse Mapping
</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ref_guide_mapping.html">Prev</a>&nbsp;</td><th width="60%" align="center">Chapter&nbsp;7.&nbsp;
Mapping
</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="ref_guide_mapping_middle.html">Next</a></td></tr></table><hr></div><div class="section" title="2.&nbsp; Reverse Mapping"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="ref_guide_pc_reverse">2.&nbsp;
Reverse Mapping
</h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="ref_guide_pc_reverse.html#ref_guide_pc_reverse_custom">2.1.
Customizing Reverse Mapping
</a></span></dt></dl></div>
<a class="indexterm" name="d5e13652"></a>
<a class="indexterm" name="d5e13654"></a>
<a class="indexterm" name="d5e13657"></a>
<p>
OpenJPA includes a <span class="emphasis"><em>reverse mapping</em></span> tool for generating
persistent class definitions, complete with metadata, from an existing database
schema. You do not have to use the reverse mapping tool to access an existing
schema; you are free to write your classes and mappings yourself, as described
in <a class="xref" href="ref_guide_mapping_middle.html" title="3.&nbsp; Meet-in-the-Middle Mapping">Section&nbsp;3, &#8220;
Meet-in-the-Middle Mapping
&#8221;</a>. The reverse mapping tool,
however, can give you an excellent starting point from which to grow your
persistent classes.
</p>
<p>
To use the reverse mapping tool, follow the steps below:
</p>
<div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">
<p>
Use the <a class="link" href="ref_guide_schema_schematool.html" title="13.&nbsp; Schema Tool"> schema tool</a> to
export your current schema to an XML schema file. You can skip this step and the
next step if you want to run the reverse mapping tool directly against the
database.
</p>
<div class="example"><a name="ref_guide_pc_reverse_schemagen"></a><p class="title"><b>Example&nbsp;7.8.&nbsp;
Reflection with the Schema Tool
</b></p><div class="example-contents">
<pre class="programlisting">
java org.apache.openjpa.jdbc.schema.SchemaTool -a reflect -f schema.xml
</pre>
</div></div><br class="example-break">
</li><li class="listitem">
<p>
Examine the generated schema file. JDBC drivers often provide incomplete or
faulty metadata, in which case the file will not exactly match the actual
schema. Alter the XML file to match the true schema. The XML format for the
schema file is described in <a class="xref" href="ref_guide_schema_xml.html" title="14.&nbsp; XML Schema Format">Section&nbsp;14, &#8220;
XML Schema Format
&#8221;</a>.
</p>
<p>
After fixing any errors in the schema file, modify the XML to include foreign
keys between all relations. The schema tool will have automatically detected
existing foreign key constraints; many schemas, however, do not employ database
foreign keys for every relation. By manually adding any missing foreign keys,
you will give the reverse mapping tool the information it needs to generate the
proper relations between the persistent classes it creates.
</p>
</li><li class="listitem">
<p>
Run the reverse mapping tool on the finished schema file. If you do not supply
the schema file to reverse map, the tool will run directly against the schema in
the database. The tool can be run via its Java class,
<a class="ulink" href="../javadoc/org/apache/openjpa/jdbc/meta/ReverseMappingTool" target="_top">
<code class="classname">org.apache.openjpa.jdbc.meta.ReverseMappingTool</code></a>.
</p>
<div class="example"><a name="ref_guide_pc_reverse_reversemappingtool"></a><p class="title"><b>Example&nbsp;7.9.&nbsp;
Using the Reverse Mapping Tool
</b></p><div class="example-contents">
<pre class="programlisting">
java org.apache.openjpa.jdbc.meta.ReverseMappingTool -pkg com.xyz -d ~/src -cp customizer.properties schema.xml
</pre>
</div></div><br class="example-break">
<p>
In addition to OpenJPA's <a class="link" href="ref_guide_conf_devtools.html" title="3.&nbsp; Command Line Configuration">standard
configuration flags</a>, including
<a class="link" href="ref_guide_conf_devtools.html#ref_guide_conf_devtools_format" title="3.1.&nbsp; Code Formatting">code formatting options</a>,
the reverse mapping tool recognizes the following command line arguments:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<p>
<code class="literal">-schemas/-s &lt;schema and table names&gt;</code>: A
comma-separated list of schema and table names to reverse map, if no XML schema
file is supplied. Each element of the list must follow the naming conventions
for the <code class="literal">openjpa.jdbc.Schemas</code> property described in
<a class="xref" href="ref_guide_schema_info.html#ref_guide_schema_info_list" title="12.1.&nbsp; Schemas List">Section&nbsp;12.1, &#8220;
Schemas List
&#8221;</a>. In fact, if this flag is
omitted, it defaults to the value of the <code class="literal">Schemas</code> property. If
the <code class="literal">Schemas</code> property is not defined, all schemas will be
reverse-mapped.
</p>
</li><li class="listitem">
<p>
<code class="literal">-package/-pkg &lt;package name&gt;</code>: The package name of the
generated classes. If no package name is given, the generated code will not
contain package declarations.
</p>
</li><li class="listitem">
<p>
<code class="literal">-directory/-d &lt;output directory&gt;</code>: All generated code
and metadata will be written to the directory at this path. If the path does not
match the package of a class, the package structure will be created beneath this
directory. Defaults to the current directory.
</p>
</li><li class="listitem">
<p>
<code class="literal">-metadata/-md &lt;class | package | none&gt;</code>: Specify the
level the metadata should be generated at. Defaults to generating a single
package-level metadata file. Set to <code class="literal">none</code> to disable orm.xml
generation.
</p>
</li><li class="listitem">
<p>
<code class="literal">-annotations/-ann &lt;true/t | false/f&gt;</code>: Set to
<code class="literal">true</code> to
generate JPA annotations in generated Java classes.
</p>
</li><li class="listitem">
<p>
<code class="literal">-accessType/-access &lt;field | property&gt;</code>: Change access
type for generated annotations. Defaults to field access.
</p>
</li><li class="listitem">
<p>
<code class="literal">-useSchemaName/-sn &lt;true/t | false/f&gt;</code>: Set this flag
to <code class="literal">true</code> to include the schema as well as table name in the
name of each generated class. This can be useful when dealing with multiple
schemas with same-named tables.
</p>
</li><li class="listitem">
<p>
<code class="literal">-useSchemaElement/-se &lt;true/t | false/f&gt;</code>: Set this
flag to <code class="literal">false</code> to exclude the schema name from the
<code class="literal">@Table</code> annotation in the generated class for each table.
If set to <code class="literal">false</code>, the schema name will also be removed from
the corresponding XML mapping files (orm.xml) that are generated by the tool.
The initialized value is true (in order to preserve backwards compatibility).
</p>
</li><li class="listitem">
<p>
<code class="literal">-useForeignKeyName/-fkn &lt;true/t | false/f&gt;</code>: Set this
flag to <code class="literal">true</code> if you would like field names for relations to
be based on the database foreign key name. By default, relation field names are
derived from the name of the related class.
</p>
</li><li class="listitem">
<p>
<code class="literal">-nullableAsObject/-no &lt;true/t | false/f&gt;</code>: By default,
all non-foreign key columns are mapped to primitives. Set this flag to <code class="literal">
true</code> to generate primitive wrapper fields instead for columns that
allow null values.
</p>
</li><li class="listitem">
<p>
<code class="literal">-blobAsObject/-bo &lt;true/t | false/f&gt;</code>: By default, all
binary columns are mapped to <code class="classname">byte[]</code> fields. Set this flag
to <code class="literal">true</code> to map them to <code class="classname">Object</code> fields
instead. Note that when mapped this way, the column is presumed to contain a
serialized Java object.
</p>
</li><li class="listitem">
<p>
<code class="literal">-primaryKeyOnJoin/-pkj &lt;true/t | false/f&gt;</code>: The
standard reverse mapping tool behavior is to map all tables with primary keys to
persistent classes. If your schema has primary keys on many-many join tables as
well, set this flag to <code class="literal">true</code> to avoid creating classes for
those tables.
</p>
</li><li class="listitem">
<p>
<code class="literal">-inverseRelations/-ir &lt;true/t | false/f&gt;</code>: Set to
<code class="literal">false</code> to prevent the creation of inverse 1-many/1-1 relations
for every many-1/1-1 relation detected.
</p>
</li><li class="listitem">
<p>
<code class="literal">-useGenericCollections/-gc &lt;true/t | false/f&gt;</code>: Set to
true to use generic collections on OneToMany and ManyToMany relations.
</p>
</li><li class="listitem">
<p>
<code class="literal">-useDatastoreIdentity/-ds &lt;true/t | false/f&gt;</code>: Set to
<code class="literal">true</code> to use datastore identity for tables that have single
numeric primary key columns. The tool typically uses application identity for
all generated classes.
</p>
</li><li class="listitem">
<p>
<code class="literal">-useBuiltinIdentityClass/-bic &lt;true/t | false/f&gt;</code>: Set
to <code class="literal">false</code> to prevent the tool from using built-in application
identity classes when possible. This will force the tool to create custom
application identity classes even when there is only one primary key column.
</p>
</li><li class="listitem">
<p>
<code class="literal">-innerIdentityClasses/-inn &lt;true/t | false/f&gt;</code>: Set to
<code class="literal">true</code> to have any generated application identity classes be
created as static inner classes within the persistent classes. Defaults to
<code class="literal">false</code>.
</p>
</li><li class="listitem">
<p>
<code class="literal">-identityClassSuffix/-is &lt;suffix&gt;</code>: Suffix to append to
class names to form application identity class names, or for inner identity
classes, the inner class name. Defaults to <code class="literal">Id</code>.
</p>
</li><li class="listitem">
<p>
<code class="literal">-typeMap/-typ &lt;type mapping&gt;</code>: A string that specifies
the default Java classes to generate for each SQL type that is seen in the
schema. The format is <code class="literal"> SQLTYPE1=JavaClass1,SQLTYPE2=JavaClass2
</code>. The SQL type name first looks for a customization based on <code class="literal">
SQLTYPE(SIZE,PRECISION)</code>, then <code class="literal">SQLTYPE(SIZE)</code>, then
<code class="literal">SQLTYPE</code>. So if a column whose type name is
<code class="literal">CHAR</code> is found, it will first look for the <code class="literal">
CHAR(50,0)</code> type name specification, then it will look for <code class="literal">
CHAR(50)</code>, and finally it will just look for <code class="literal">CHAR</code>.
For example, to generate a char array for every <code class="literal">CHAR</code> column
whose size is exactly 50, and to generate a <code class="literal">short</code> for every
type name of <code class="literal">INTEGER</code>, you might specify: <code class="literal">
CHAR(50)=char[],INTEGER=short</code>. Note that since various databases
report different type names differently, one database's type name specification
might not work for another database. Enable <code class="literal">TRACE</code> level
logging on the <code class="literal">MetaData</code> channel to track which type names
OpenJPA is examining.
</p>
</li><li class="listitem">
<p>
<code class="literal">-customizerClass/-cc &lt;class name&gt;</code>: The full class name
of a
<a class="ulink" href="../javadoc/org/apache/openjpa/jdbc/meta/ReverseCustomizer.html" target="_top">
<code class="classname">org.apache.openjpa.jdbc.meta.ReverseCustomizer</code></a>
customization plugin. If you do not specify a reverse customizer of your own,
the system defaults to a
<a class="ulink" href="../javadoc/org/apache/openjpa/jdbc/meta/PropertiesReverseCustomizer.html" target="_top">
<code class="classname">PropertiesReverseCustomizer</code></a>. This customizer
allows you to specify simple customization options in the properties file given
with the <code class="literal">-customizerProperties</code> flag below. We present the
available property keys <a class="link" href="ref_guide_pc_reverse.html#ref_guide_pc_reverse_custom" title="2.1.&nbsp; Customizing Reverse Mapping">
below</a>.
</p>
</li><li class="listitem">
<p>
<code class="literal">-customizerProperties/-cp &lt;properties file or resource&gt;</code>
: The path or resource name of a properties file to pass to the reverse
customizer on initialization.
</p>
</li><li class="listitem">
<p>
<code class="literal">-customizer./-c.&lt;property name&gt; &lt;property value&gt;</code>
: The given property name will be matched with the corresponding Java bean
property in the specified reverse customizer, and set to the given value.
</p>
</li></ul></div>
<p>
Running the tool will generate <code class="filename">.java</code> files for each
generated class (and its application identity class, if applicable), along with
JPA annotations (if enabled by setting <code class="literal">-annotations true</code>),
or an <code class="filename">orm.xml</code> file (if not disabled with <code class="literal">
-metadata none</code>) containing the corresponding persistence metadata.
</p>
</li><li class="listitem">
<p>
Examine the generated class, metadata, and mapping information, and modify it as
necessary. Remember that the reverse mapping tool only provides a starting
point, and you are free to make whatever modifications you like to the code it
generates.
</p>
<p>
After you are satisfied with the generated classes and their mappings, you
should first compile the classes with <code class="literal">javac</code>, <code class="literal">
jikes</code>, or your favorite Java compiler. Make sure the classes are
located in the directory corresponding to the <code class="literal">-package</code> flag
you gave the reverse mapping tool. Next, if you have generated an <code class="filename">
orm.xml</code>, move that file to a <code class="filename">META-INF</code> directory
within a directory in your classpath. Finally, enhance the classes
if necessary (see <a class="xref" href="ref_guide_pc_enhance.html" title="2.&nbsp; Enhancement">Section&nbsp;2, &#8220;
Enhancement
&#8221;</a>).
</p>
</li></ol></div>
<p>
Your persistent classes are now ready to access your existing schema.
</p>
<div class="section" title="2.1.&nbsp; Customizing Reverse Mapping"><div class="titlepage"><div><div><h3 class="title" id="ref_guide_pc_reverse_custom">2.1.&nbsp;
Customizing Reverse Mapping
</h3></div></div></div>
<p>
The <code class="classname">org.apache.openjpa.jdbc.meta.ReverseCustomizer</code> plugin
interface allows you to customize the reverse mapping process. See the class
<a class="ulink" href="../javadoc/org/apache/openjpa/jdbc/meta/ReverseCustomizer.html" target="_top">
Javadoc</a> for details on the hooks that this interface provides. Specify
the concrete plugin implementation to use with the <code class="literal">
-customizerClass/-cc</code> command-line flag, described in the preceding
section.
</p>
<p>
By default, the reverse mapping tool uses a
<a class="ulink" href="../javadoc/org/apache/openjpa/jdbc/meta/PropertiesReverseCustomizer.html" target="_top">
<code class="classname">org.apache.openjpa.jdbc.meta.PropertiesReverseCustomizer</code>
</a>. This customizer allows you to perform relatively simple
customizations through the properties file named with the <code class="literal">
-customizerProperties</code> tool flag. The customizer recognizes the
following properties:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<p>
<code class="literal">&lt;table name&gt;.table-type &lt;type&gt;</code>: Override the
default type of the table with name <code class="literal">&lt;table name&gt;</code>.
Legal values are:
</p>
<div class="itemizedlist"><ul class="itemizedlist" type="circle"><li class="listitem">
<p>
<code class="literal">base</code>: Primary table for a base class.
</p>
</li><li class="listitem">
<p>
<code class="literal">secondary</code>: Secondary table for a class. The table must have
a foreign key joining to a class table.
</p>
</li><li class="listitem">
<p>
<code class="literal">secondary-outer</code>: Outer-joined secondary table for a class.
The table must have a foreign key joining to a class table.
</p>
</li><li class="listitem">
<p>
<code class="literal">association</code>: Association table. The table must have two
foreign keys to class tables.
</p>
</li><li class="listitem">
<p>
<code class="literal">collection</code>: Collection table. The table must have one
foreign key to a class table and one data column.
</p>
</li><li class="listitem">
<p>
<code class="literal">subclass</code>: A joined subclass table. The table must have a
foreign key to the superclass' table.
</p>
</li><li class="listitem">
<p>
<code class="literal">none</code>: The table should not be reverse-mapped.
</p>
</li></ul></div>
</li><li class="listitem">
<p>
<code class="literal">&lt;class name&gt;.rename &lt;new class name&gt;</code>: Override
the given tool-generated name <code class="literal">&lt;class name&gt;</code> with a new
value. Use full class names, including package. You are free to rename a class
to a new package. Specify a value of <code class="literal">none</code> to reject the class
and leave the corresponding table unmapped.
</p>
</li><li class="listitem">
<p>
<code class="literal">&lt;table name&gt;.class-name &lt;new class name&gt;</code>: Assign
the given fully-qualified class name to the type created from the table with
name <code class="literal">&lt;table name&gt;</code>. Use a value of <code class="literal">none
</code> to prevent reverse mapping this table. This property can be used in
place of the <code class="literal">rename</code> property.
</p>
</li><li class="listitem">
<p>
<code class="literal">&lt;class name&gt;.identity &lt;datastore | builtin | identity class
name&gt;</code>: Set this property to <code class="literal">datastore</code> to use
datastore identity for the class <code class="literal">&lt;class name&gt;</code>,
<code class="literal">builtin</code> to use a built-in identity class, or the desired
application identity class name. Give full class names, including package. You
are free to change the package of the identity class this way. If the persistent
class has been renamed, use the new class name for this property key. Remember
that datastore identity requires a table with a single numeric primary key
column, and built-in identity requires a single primary key column of any type.
</p>
</li><li class="listitem">
<p>
<code class="literal">&lt;class name&gt;.&lt;field name&gt;.rename &lt;new field name&gt;
</code>: Override the tool-generated <code class="literal">&lt;field name&gt;</code> in
class <code class="literal">&lt;class name&gt;</code> with the given name. Use the field
owner's full class name in the property key. If the field owner's class was
renamed, use the new class name. The property value should be the new field
name, without the preceding class name. Use a value of <code class="literal">none</code>
to reject the generated mapping and remove the field from the class.
</p>
</li><li class="listitem">
<p>
<code class="literal">&lt;table name&gt;.&lt;column name&gt;.field-name &lt;new field
name&gt;</code>: Set the generated field name for the <code class="literal">&lt;table
name&gt;</code> table's <code class="literal">&lt;column name&gt;</code> column. If
this is a multi-column mapping, any of the columns can be used. Use a value of
<code class="literal">none</code> to prevent the column and its associated columns from
being reverse-mapped.
</p>
</li><li class="listitem">
<p>
<code class="literal">&lt;class name&gt;.&lt;field name&gt;.type &lt;field type&gt;</code>
: The type to give the named field. Use full class names. If the field or the
field's owner class has been renamed, use the new name.
</p>
</li><li class="listitem">
<p>
<code class="literal">&lt;class name&gt;.&lt;field name&gt;.value</code>: The initial
value for the named field. The given string will be placed as-is in the
generated Java code, so be sure it is valid Java. If the field or the field's
owner class has been renamed, use the new name.
</p>
</li></ul></div>
<p>
All property keys are optional; if not specified, the customizer keeps the
default value generated by the reverse mapping tool.
</p>
<div class="example"><a name="ref_guide_pc_reverse_custom_ex"></a><p class="title"><b>Example&nbsp;7.10.&nbsp;
Customizing Reverse Mapping with Properties
</b></p><div class="example-contents">
<pre class="programlisting">
java org.apache.openjpa.jdbc.meta.ReverseMappingTool -pkg com.xyz -cp custom.properties schema.xml
</pre>
<p>
Example <code class="filename">custom.properties</code>:
</p>
<pre class="programlisting">
com.xyz.TblMagazine.rename: com.xyz.Magazine
com.xyz.TblArticle.rename: com.xyz.Article
com.xyz.TblPubCompany.rename: com.xyz.pub.Company
com.xyz.TblSysInfo.rename: none
com.xyz.Magazine.allArticles.rename: articles
com.xyz.Magazine.articles.type: java.util.Collection
com.xyz.Magazine.articles.value: new TreeSet()
com.xyz.Magazine.identity: datastore
com.xyz.pub.Company.identity: com.xyz.pub.CompanyId
</pre>
</div></div><br class="example-break">
</div>
</div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ref_guide_mapping.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="ref_guide_mapping.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="ref_guide_mapping_middle.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter&nbsp;7.&nbsp;
Mapping
&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="manual.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;3.&nbsp;
Meet-in-the-Middle Mapping
</td></tr></table></div></body></html>