<?xml version="1.0" encoding="UTF-8"?> | |
<!-- | |
Licensed to the Apache Software Foundation (ASF) under one | |
or more contributor license agreements. See the NOTICE file | |
distributed with this work for additional information | |
regarding copyright ownership. The ASF licenses this file | |
to you under the Apache License, Version 2.0 (the | |
"License"); you may not use this file except in compliance | |
with the License. You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, | |
software distributed under the License is distributed on an | |
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
KIND, either express or implied. See the License for the | |
specific language governing permissions and limitations | |
under the License. | |
--> | |
<chapter id="ref_guide_mapping"> | |
<title> | |
Mapping | |
</title> | |
<indexterm zone="ref_guide_mapping"> | |
<primary> | |
mapping metadata | |
</primary> | |
</indexterm> | |
<para> | |
The JPA Overview's <xref linkend="jpa_overview_mapping"/> explains | |
object-relational mapping under JPA. This chapter reviews the mapping utilities | |
OpenJPA provides and examines OpenJPA features that go beyond the JPA | |
specification. | |
</para> | |
<section id="ref_guide_mapping_mappingtool"> | |
<title> | |
Forward Mapping | |
</title> | |
<indexterm zone="ref_guide_mapping_mappingtool"> | |
<primary> | |
forward mapping | |
</primary> | |
</indexterm> | |
<indexterm zone="ref_guide_mapping_mappingtool"> | |
<primary> | |
mapping tool | |
</primary> | |
<seealso> | |
forward mapping | |
</seealso> | |
</indexterm> | |
<indexterm> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
forward mapping | |
</secondary> | |
<see> | |
forward mapping | |
</see> | |
</indexterm> | |
<para> | |
<emphasis>Forward mapping</emphasis> is the process of creating mappings and | |
their corresponding database schema from your object model. OpenJPA supports | |
forward mapping through the <emphasis>mapping tool</emphasis>. The next section | |
presents several common mapping tool use cases. You can invoke the tool through | |
its Java class, | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/MappingTool"><classname> | |
org.apache.openjpa.jdbc.meta.MappingTool</classname></ulink>. | |
</para> | |
<note> | |
<para> | |
<xref linkend="ref_guide_integration_mappingtool"/> describes the mapping | |
tool Ant task. | |
</para> | |
</note> | |
<example id="ref_guide_mapping_mappingtool_typical"> | |
<title> | |
Using the Mapping Tool | |
</title> | |
<programlisting> | |
java org.apache.openjpa.jdbc.meta.MappingTool Magazine.java | |
</programlisting> | |
</example> | |
<para> | |
In addition to the universal flags of the | |
<link linkend="ref_guide_conf_devtools">configuration framework</link>, the | |
mapping tool accepts the following command line arguments: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>-schemaAction/-sa <add | refresh | drop | build | retain | reflect | createDB | dropDB | import | export | none> | |
</literal>: The action to take on the schema. These options correspond to the | |
same-named actions on the schema tool described in | |
<xref linkend="ref_guide_schema_schematool"/>. 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 <literal>add</literal> action or the | |
<literal>build</literal> action. Otherwise you may end up inadvertently | |
dropping schema components that are used by classes you are not | |
currently running the tool over. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-schemaFile/-sf <stdout | output file></literal>: 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 <link linkend="ref_guide_schema_schematool"> schema tool</link>. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-sqlFile/-sql <stdout | output file></literal>: Use this option | |
to write the planned schema modifications to a SQL script rather than modify the | |
database. Combine this with a <literal>schemaAction</literal> of <literal>build | |
</literal> to generate a script that recreates the schema for the current | |
mappings, even if the schema already exists. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-dropTables/-dt <true/t | false/f></literal>: Corresponds to the | |
same-named option on the schema tool. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-dropSequences/-dsq <true/t | false/f></literal>: Corresponds to | |
the same-named option on the schema tool. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-openjpaTables/-ot <true/t | false/f></literal>: Corresponds to | |
the same-named option on the schema tool. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-ignoreErrors/-i <true/t | false/f></literal>: Corresponds to | |
the same-named option on the schema tool. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-schemas/-s <schema and table names></literal>: Corresponds to | |
the same-named option on the schema tool. This option is ignored if <literal> | |
readSchema</literal> is not set to <literal>true</literal>. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-readSchema/-rs <true/t | false/f></literal>: Set this option to | |
<literal>true</literal> 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. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-primaryKeys/-pk <true/t | false/f></literal>: Whether to read | |
and manipulate primary key information of existing tables. Defaults to false. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-foreignKeys/-fk <true/t | false/f></literal>: 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. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-indexes/-ix <true/t | false/f></literal>: 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. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-sequences/-sq <true/t | false/f></literal>: Whether to | |
manipulate sequences. Defaults to true. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-meta/-m <true/t | false/f></literal>: Whether the given action | |
applies to metadata rather than or in addition to mappings. | |
</para> | |
</listitem> | |
</itemizedlist> | |
<para> | |
The mapping tool also uses an <literal>-action/-a</literal> argument to specify | |
the action to take on each class. The available actions are: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>buildSchema</literal>: 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. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>validate</literal>: 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. | |
</para> | |
</listitem> | |
</itemizedlist> | |
<para> | |
Each additional argument to the tool should be one of: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
The full name of a persistent class. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
The .java file for a persistent class. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
The <filename>.class</filename> file of a persistent class. | |
</para> | |
</listitem> | |
</itemizedlist> | |
<para> | |
If you do not supply any arguments to the mapping tool, it will run on the | |
classes in your persistent classes list (see | |
<xref linkend="ref_guide_pc_pcclasses"/>). | |
</para> | |
<para> | |
The mappings generated by the mapping tool are stored by the system <emphasis> | |
mapping factory</emphasis>. <xref linkend="ref_guide_mapping_factory"/> | |
discusses your mapping factory options. | |
</para> | |
<section id="ref_guide_mapping_mappingtool_examples"> | |
<title> | |
Using the Mapping Tool | |
</title> | |
<indexterm zone="ref_guide_mapping_mappingtool_examples"> | |
<primary> | |
mapping tool | |
</primary> | |
<secondary> | |
use cases | |
</secondary> | |
</indexterm> | |
<para> | |
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 <xref linkend="jpa_overview_mapping"/> | |
of the JPA Overview to override any unsatisfactory defaults, run the | |
mapping tool on your persistent classes. The default <literal>buildSchema | |
</literal> mapping tool action manipulates the database schema to | |
match your mappings. It fails if any of your mappings don't match your object | |
model. | |
</para> | |
<example id="ref_guide_mapping_mappingtool_buildschema"> | |
<title> | |
Creating the Relational Schema from Mappings | |
</title> | |
<programlisting> | |
java org.apache.openjpa.jdbc.meta.MappingTool Magazine.java | |
</programlisting> | |
</example> | |
<para> | |
To drop the schema for a persistent class, set the mapping tool's <literal> | |
schemaAction</literal> to <literal>drop</literal>. | |
</para> | |
<example id="ref_guide_mapping_mappingtool_cleanup_tables"> | |
<title> | |
Refreshing entire schema and cleaning out tables | |
</title> | |
<indexterm zone="ref_guide_mapping_mappingtool_cleanup_tables"> | |
<primary> | |
testing | |
</primary> | |
<secondary> | |
Rebuild mappings and clean tables | |
</secondary> | |
</indexterm> | |
<programlisting> | |
java org.apache.openjpa.jdbc.meta.MappingTool -schemaAction add,deleteTableContents | |
</programlisting> | |
</example> | |
<example id="ref_guide_mapping_mappingtool_dropschema"> | |
<title> | |
Dropping Mappings and Association Schema | |
</title> | |
<programlisting> | |
java org.apache.openjpa.jdbc.meta.MappingTool -schemaAction drop Magazine.java | |
</programlisting> | |
</example> | |
</section> | |
<section id="ref_guide_ddl_examples"> | |
<title> | |
Generating DDL SQL | |
</title> | |
<indexterm zone="ref_guide_ddl_examples"> | |
<primary> | |
mapping tool | |
</primary> | |
<secondary> | |
DDL generation | |
</secondary> | |
</indexterm> | |
<indexterm zone="ref_guide_ddl_examples"> | |
<primary> | |
DDL | |
</primary> | |
<secondary> | |
with mapping tool | |
</secondary> | |
</indexterm> | |
<para> | |
The examples below show how to use the mapping tool to generate DDL SQL scripts, | |
rather than modifying the database directly. | |
</para> | |
<example id="ref_guid_mapping_ddl_full_ddl"> | |
<title> | |
Create DDL for Current Mappings | |
</title> | |
<para> | |
This example uses your existing mappings to determine the needed schema, then | |
writes the SQL to create that schema to <filename>create.sql</filename>. | |
</para> | |
<programlisting> | |
java org.apache.openjpa.jdbc.meta.MappingTool -schemaAction build -sql create.sql Magazine.java | |
</programlisting> | |
</example> | |
<example id="ref_guid_mapping_ddl_part_ddl"> | |
<title> | |
Create DDL to Update Database for Current Mappings | |
</title> | |
<para> | |
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 | |
<filename>update.sql</filename>. | |
</para> | |
<programlisting> | |
java org.apache.openjpa.jdbc.meta.MappingTool -sql update.sql Magazine.java | |
</programlisting> | |
</example> | |
</section> | |
<section id="ref_guide_mapping_synch"> | |
<title> | |
Runtime Forward Mapping | |
</title> | |
<indexterm zone="ref_guide_mapping_synch"> | |
<primary> | |
forward mapping | |
</primary> | |
<secondary> | |
automatic runtime mapping | |
</secondary> | |
</indexterm> | |
<indexterm zone="ref_guide_mapping_synch"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
automatic runtime mapping | |
</secondary> | |
</indexterm> | |
<para> | |
You can configure OpenJPA to automatically run the mapping tool at runtime | |
through the <link linkend="openjpa.jdbc.SynchronizeMappings"><literal> | |
openjpa.jdbc.SynchronizeMappings</literal></link> 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. | |
</para> | |
<para> | |
In order to enable automatic runtime mapping, you must first list all your | |
persistent classes as described in <xref linkend="ref_guide_pc_pcclasses"/>. | |
</para> | |
<para> | |
OpenJPA will run the mapping tool on these classes when your application obtains | |
its first <classname>EntityManager</classname>. | |
</para> | |
<para> | |
The <literal>openjpa.jdbc.SynchronizeMappings</literal> property is a plugin | |
string (see <xref linkend="ref_guide_conf_plugins"/>) where the class | |
name is the mapping tool action to invoke, and the properties are the | |
<classname>MappingTool</classname> class' JavaBean properties. These properties | |
correspond go the long versions of the tool's command line flags. | |
</para> | |
<example id="ref_guide_mapping_synchex"> | |
<title> | |
Configuring Runtime Forward Mapping | |
</title> | |
<programlisting> | |
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> | |
</programlisting> | |
<para> | |
The setting above corresponds to running the following command: | |
</para> | |
<programlisting> | |
java org.apache.openjpa.jdbc.meta.MappingTool -action buildSchema -foreignKeys true | |
</programlisting> | |
</example> | |
</section> | |
</section> | |
<section id="ref_guide_pc_reverse"> | |
<title> | |
Reverse Mapping | |
</title> | |
<indexterm zone="ref_guide_pc_reverse"> | |
<primary> | |
reverse mapping | |
</primary> | |
</indexterm> | |
<indexterm zone="ref_guide_pc_reverse"> | |
<primary> | |
reverse mapping tool | |
</primary> | |
<seealso> | |
reverse mapping | |
</seealso> | |
</indexterm> | |
<indexterm> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
reverse mapping | |
</secondary> | |
<see> | |
reverse mapping | |
</see> | |
</indexterm> | |
<para> | |
OpenJPA includes a <emphasis>reverse mapping</emphasis> 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 <xref linkend="ref_guide_mapping_middle"/>. The reverse mapping tool, | |
however, can give you an excellent starting point from which to grow your | |
persistent classes. | |
</para> | |
<para> | |
To use the reverse mapping tool, follow the steps below: | |
</para> | |
<orderedlist> | |
<listitem> | |
<para> | |
Use the <link linkend="ref_guide_schema_schematool"> schema tool</link> 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. | |
</para> | |
<example id="ref_guide_pc_reverse_schemagen"> | |
<title> | |
Reflection with the Schema Tool | |
</title> | |
<programlisting> | |
java org.apache.openjpa.jdbc.schema.SchemaTool -a reflect -f schema.xml | |
</programlisting> | |
</example> | |
</listitem> | |
<listitem> | |
<para> | |
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 <xref linkend="ref_guide_schema_xml"/>. | |
</para> | |
<para> | |
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. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
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, | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ReverseMappingTool"> | |
<classname>org.apache.openjpa.jdbc.meta.ReverseMappingTool</classname></ulink>. | |
</para> | |
<example id="ref_guide_pc_reverse_reversemappingtool"> | |
<title> | |
Using the Reverse Mapping Tool | |
</title> | |
<programlisting> | |
java org.apache.openjpa.jdbc.meta.ReverseMappingTool -pkg com.xyz -d ~/src -cp customizer.properties schema.xml | |
</programlisting> | |
</example> | |
<para> | |
In addition to OpenJPA's <link linkend="ref_guide_conf_devtools">standard | |
configuration flags</link>, including | |
<link linkend="ref_guide_conf_devtools_format">code formatting options</link>, | |
the reverse mapping tool recognizes the following command line arguments: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>-schemas/-s <schema and table names></literal>: 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 <literal>openjpa.jdbc.Schemas</literal> property described in | |
<xref linkend="ref_guide_schema_info_list"/>. In fact, if this flag is | |
omitted, it defaults to the value of the <literal>Schemas</literal> property. If | |
the <literal>Schemas</literal> property is not defined, all schemas will be | |
reverse-mapped. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-package/-pkg <package name></literal>: The package name of the | |
generated classes. If no package name is given, the generated code will not | |
contain package declarations. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-directory/-d <output directory></literal>: 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. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-metadata/-md <class | package | none></literal>: Specify the | |
level the metadata should be generated at. Defaults to generating a single | |
package-level metadata file. Set to <literal>none</literal> to disable orm.xml | |
generation. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-annotations/-ann <true/t | false/f></literal>: Set to true to | |
generate JPA annotations in generated java classes. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-accessType/-access <field | property></literal>: Change access | |
type for generated annotations. Defaults to field access. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-useSchemaName/-sn <true/t | false/f></literal>: Set this flag | |
to <literal>true</literal> 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. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-useForeignKeyName/-fkn <true/t | false/f></literal>: Set this | |
flag to <literal>true</literal> 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. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-nullableAsObject/-no <true/t | false/f></literal>: By default, | |
all non-foreign key columns are mapped to primitives. Set this flag to <literal> | |
true</literal> to generate primitive wrapper fields instead for columns that | |
allow null values. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-blobAsObject/-bo <true/t | false/f></literal>: By default, all | |
binary columns are mapped to <classname>byte[]</classname> fields. Set this flag | |
to <literal>true</literal> to map them to <classname>Object</classname> fields | |
instead. Note that when mapped this way, the column is presumed to contain a | |
serialized Java object. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-primaryKeyOnJoin/-pkj <true/t | false/f></literal>: 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 <literal>true</literal> to avoid creating classes for | |
those tables. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-inverseRelations/-ir <true/t | false/f></literal>: Set to | |
<literal>false</literal> to prevent the creation of inverse 1-many/1-1 relations | |
for every many-1/1-1 relation detected. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-useGenericCollections/-gc <true/t | false/f></literal>: Set to | |
true to use generic collections on OneToMany and ManyToMany relations (requires | |
JDK 1.5 or higher). | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-useDatastoreIdentity/-ds <true/t | false/f></literal>: Set to | |
<literal>true</literal> to use datastore identity for tables that have single | |
numeric primary key columns. The tool typically uses application identity for | |
all generated classes. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-useBuiltinIdentityClass/-bic <true/t | false/f></literal>: Set | |
to <literal>false</literal> to prevent the tool from using built-in application | |
identity classes when possible. This will force the tool to to create custom | |
application identity classes even when there is only one primary key column. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-innerIdentityClasses/-inn <true/t | false/f></literal>: Set to | |
<literal>true</literal> to have any generated application identity classes be | |
created as static inner classes within the persistent classes. Defaults to | |
<literal>false</literal>. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-identityClassSuffix/-is <suffix></literal>: Suffix to append to | |
class names to form application identity class names, or for inner identity | |
classes, the inner class name. Defaults to <literal>Id</literal>. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-typeMap/-typ <type mapping></literal>: A string that specifies | |
the default Java classes to generate for each SQL type that is seen in the | |
schema. The format is <literal> SQLTYPE1=JavaClass1,SQLTYPE2=JavaClass2 | |
</literal>. The SQL type name first looks for a customization based on <literal> | |
SQLTYPE(SIZE,PRECISION)</literal>, then <literal>SQLTYPE(SIZE)</literal>, then | |
<literal>SQLTYPE(SIZE,PRECISION)</literal>. So if a column whose type name is | |
<literal>CHAR</literal> is found, it will first look for the <literal> | |
CHAR(50,0)</literal> type name specification, then it will look for <literal> | |
CHAR(50)</literal>, and finally it will just look for <literal>CHAR</literal>. | |
For example, to generate a char array for every <literal>CHAR</literal> column | |
whose size is exactly 50, and to generate a <literal>short</literal> for every | |
type name of <literal>INTEGER</literal>, you might specify: <literal> | |
CHAR(50)=char[],INTEGER=short</literal>. Note that since various databases | |
report different type names differently, one database's type name specification | |
might not work for another database. Enable <literal>TRACE</literal> level | |
logging on the <literal>MetaData</literal> channel to track which type names | |
OpenJPA is examining. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-customizerClass/-cc <class name></literal>: The full class name | |
of a | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ReverseCustomizer.html"> | |
<classname>org.apache.openjpa.jdbc.meta.ReverseCustomizer</classname></ulink> | |
customization plugin. If you do not specify a reverse customizer of your own, | |
the system defaults to a | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/PropertiesReverseCustomizer.html"> | |
<classname>PropertiesReverseCustomizer</classname></ulink>. This customizer | |
allows you to specify simple customization options in the properties file given | |
with the <literal>-customizerProperties</literal> flag below. We present the | |
available property keys <link linkend="ref_guide_pc_reverse_custom"> | |
below</link>. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-customizerProperties/-cp <properties file or resource></literal> | |
: The path or resource name of a properties file to pass to the reverse | |
customizer on initialization. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>-customizer./-c.<property name> <property value></literal> | |
: The given property name will be matched with the corresponding Java bean | |
property in the specified reverse customizer, and set to the given value. | |
</para> | |
</listitem> | |
</itemizedlist> | |
<para> | |
Running the tool will generate <filename>.java</filename> files for each | |
generated class (and its application identity class, if applicable), along with | |
JPA annotations (if enabled by setting <literal>-annotations true</literal>), | |
or an <filename>orm.xml</filename> file (if not disabled with <literal> | |
-metadata none</literal>) containing the corresponding persistence metadata. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
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. | |
</para> | |
<para> | |
After you are satisfied with the generated classes and their mappings, you | |
should first compile the classes with <literal>javac</literal>, <literal> | |
jikes</literal>, or your favorite Java compiler. Make sure the classes are | |
located in the directory corresponding to the <literal>-package</literal> flag | |
you gave the reverse mapping tool. Next, if you have generated an <filename> | |
orm.xml</filename>, move that file to a <filename>META-INF</filename> directory | |
within a directory in your classpath. Finally, enhance the classes | |
if necessary (see <xref linkend="ref_guide_pc_enhance"/>). | |
</para> | |
</listitem> | |
</orderedlist> | |
<para> | |
Your persistent classes are now ready to access your existing schema. | |
</para> | |
<section id="ref_guide_pc_reverse_custom"> | |
<title> | |
Customizing Reverse Mapping | |
</title> | |
<para> | |
The <classname>org.apache.openjpa.jdbc.meta.ReverseCustomizer</classname> plugin | |
interface allows you to customze the reverse mapping process. See the class | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ReverseCustomizer.html"> | |
Javadoc</ulink> for details on the hooks that this interface provides. Specify | |
the concrete plugin implementation to use with the <literal> | |
-customizerClass/-cc</literal> command-line flag, described in the preceding | |
section. | |
</para> | |
<para> | |
By default, the reverse mapping tool uses a | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/PropertiesReverseCustomizer.html"> | |
<classname>org.apache.openjpa.jdbc.meta.PropertiesReverseCustomizer</classname> | |
</ulink>. This customizer allows you to perform relatively simple | |
customizations through the properties file named with the <literal> | |
-customizerProperties</literal> tool flag. The customizer recognizes the | |
following properties: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal><table name>.table-type <type></literal>: Override the | |
default type of the table with name <literal><table name></literal>. | |
Legal values are: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>base</literal>: Primary table for a base class. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>secondary</literal>: Secondary table for a class. The table must have | |
a foreign key joining to a class table. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>secondary-outer</literal>: Outer-joined secondary table for a class. | |
The table must have a foreign key joining to a class table. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>association</literal>: Association table. The table must have two | |
foreign keys to class tables. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>collection</literal>: Collection table. The table must have one | |
foreign key to a class table and one data column. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>subclass</literal>: A joined subclass table. The table must have a | |
foreign key to the superclass' table. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>none</literal>: The table should not be reverse-mapped. | |
</para> | |
</listitem> | |
</itemizedlist> | |
</listitem> | |
<listitem> | |
<para> | |
<literal><class name>.rename <new class name></literal>: Override | |
the given tool-generated name <literal><class name></literal> 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 <literal>none</literal> to reject the class | |
and leave the corresponding table unmapped. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal><table name>.class-name <new class name></literal>: Assign | |
the given fully-qualified class name to the type created from the table with | |
name <literal><table name></literal>. Use a value of <literal>none | |
</literal> to prevent reverse mapping this table. This property can be used in | |
place of the <literal>rename</literal> property. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal><class name>.identity <datastore | builtin | identity class | |
name></literal>: Set this property to <literal>datastore</literal> to use | |
datastore identity for the class <literal><class name></literal>, | |
<literal>builtin</literal> 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. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal><class name>.<field name>.rename <new field name> | |
</literal>: Override the tool-generated <literal><field name></literal> in | |
class <literal><class name></literal> 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 <literal>none</literal> | |
to reject the generated mapping and remove the field from the class. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal><table name>.<column name>.field-name <new field | |
name></literal>: Set the generated field name for the <literal><table | |
name></literal> table's <literal><column name></literal> column. If | |
this is a multi-column mapping, any of the columns can be used. Use a value of | |
<literal>none</literal> to prevent the column and its associated columns from | |
being reverse-mapped. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal><class name>.<field name>.type <field type></literal> | |
: 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. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal><class name>.<field name>.value</literal>: 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. | |
</para> | |
</listitem> | |
</itemizedlist> | |
<para> | |
All property keys are optional; if not specified, the customizer keeps the | |
default value generated by the reverse mapping tool. | |
</para> | |
<example id="ref_guide_pc_reverse_custom_ex"> | |
<title> | |
Customizing Reverse Mapping with Properties | |
</title> | |
<programlisting> | |
java org.apache.openjpa.jdbc.meta.ReverseMappingTool -pkg com.xyz -cp custom.properties schema.xml | |
</programlisting> | |
<para> | |
Example <filename>custom.properties</filename>: | |
</para> | |
<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 | |
</programlisting> | |
</example> | |
</section> | |
</section> | |
<section id="ref_guide_mapping_middle"> | |
<title> | |
Meet-in-the-Middle Mapping | |
</title> | |
<indexterm zone="ref_guide_pc_reverse"> | |
<primary> | |
meet-in-the-middle mapping | |
</primary> | |
</indexterm> | |
<indexterm zone="ref_guide_pc_reverse"> | |
<primary> | |
reverse mapping tool | |
</primary> | |
<seealso> | |
reverse mapping | |
</seealso> | |
</indexterm> | |
<indexterm> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
meet-in-the-middle mapping | |
</secondary> | |
<see> | |
meet-in-the-middle mapping | |
</see> | |
</indexterm> | |
<para> | |
In the <emphasis>meet-in-the-middle</emphasis> | |
mapping approach, you control both the relational model and the object model. It | |
is up to you to define the mappings between these models. The mapping | |
tool's <literal>validate</literal> action is useful to meet-in-the-middle | |
mappers. This action verifies that the mapping information for a class matches | |
the class definition and the existing schema. It throws an informative exception | |
when your mappings are incorrect. | |
</para> | |
<example id="ref_guide_mapping_mappingtool_validate"> | |
<title> | |
Validating Mappings | |
</title> | |
<programlisting> | |
java org.apache.openjpa.jdbc.meta.MappingTool -action validate Magazine.java | |
</programlisting> | |
</example> | |
<para> | |
The <literal>buildSchema</literal> action we discussed in | |
<xref linkend="ref_guide_mapping_mappingtool"/> is also somewhat useful | |
during meet-in-the-middle mapping. Unlike the <literal>validate</literal> | |
action, which throws an exception if your mapping data does not match the | |
existing schema, the <literal>buildSchema</literal> action assumes your mapping | |
data is correct, and modifies the schema to match your mappings. This lets you | |
modify your mapping data manually, but saves you the hassle of using your | |
database's tools to bring the schema up-to-date. | |
</para> | |
</section> | |
<section id="ref_guide_mapping_defaults"> | |
<title> | |
Mapping Defaults | |
</title> | |
<indexterm zone="ref_guide_mapping_defaults"> | |
<primary> | |
MappingDefaults | |
</primary> | |
</indexterm> | |
<indexterm> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
defaults | |
</secondary> | |
<see> | |
MappingDefaults | |
</see> | |
</indexterm> | |
<para> | |
The previous sections showed how to use the mapping tool to generate default | |
mappings. But how does the mapping tool know what mappings to generate? The | |
answer lies in the | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/MappingDefaults.html"> | |
<classname>org.apache.openjpa.jdbc.meta.MappingDefaults</classname></ulink> | |
interface. OpenJPA uses an instance of this interface to decide how to name | |
tables and columns, where to put foreign keys, and generally how to create a | |
schema that matches your object model. | |
</para> | |
<important> | |
<para> | |
OpenJPA relies on foreign key constraint information at runtime to order SQL | |
appropriately. Be sure to set your mapping defaults to reflect your existing | |
database constraints, set the schema factory to reflect on the database for | |
constraint information (see <xref linkend="ref_guide_schema_info_factory"/>), | |
or use explicit foreign key mappings as described in | |
<xref linkend="ref_guide_mapping_jpa_fk"/>. | |
</para> | |
</important> | |
<para> | |
The <link linkend="openjpa.jdbc.MappingDefaults"><literal> | |
openjpa.jdbc.MappingDefaults</literal></link> configuration property controls | |
the <classname>MappingDefaults</classname> interface implementation in use. This | |
is a plugin property (see <xref linkend="ref_guide_conf_plugins"/>), so | |
you can substitute your own implementation or configure the existing ones. | |
OpenJPA includes the following standard implementations: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>jpa</literal>: Provides defaults in compliance with the JPA standard. | |
This is an alias for the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/PersistenceMappingDefaults.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.PersistenceMappingDefaults | |
</classname></ulink> class. This class extends the <classname> | |
MappingDefaultsImpl</classname> class described below, so it has all the same | |
properties (though with different default values), as well as: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>PrependFieldNameToJoinTableInverseJoinColumns</literal>: Whether to | |
prepend the owning field name to the names of inverse join columns in join | |
tables. Defaults to true per the JPA specification. Set to false for | |
compatibility with older OpenJPA versions which did not prepend the field name. | |
</para> | |
</listitem> | |
</itemizedlist> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>default</literal>: This is an alias for the | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/MappingDefaultsImpl.html"> | |
<classname>org.apache.openjpa.jdbc.meta.MappingDefaultsImpl</classname></ulink> | |
class. This default implementation is highly configurable. It has the following | |
properties: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>DefaultMissingInfo</literal>: Whether to default missing column and | |
table names rather than throw an exception. If set to false, full explicit | |
mappings are required at runtime and when using mapping tool actions like | |
<literal>buildSchema</literal> and <literal>validate</literal>. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>BaseClassStrategy</literal>: The default mapping strategy for base | |
classes. You can specify a built-in strategy alias or the full class name of a | |
<link linkend="ref_guide_mapping_custom_class">custom class strategy</link>. | |
You can also use OpenJPA's plugin format (see | |
<xref linkend="ref_guide_conf_plugins"/>) to pass arguments to the | |
strategy instance. See the | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/strats/package-summary.html"> | |
<literal>org.apache.openjpa.jdbc.meta.strats</literal></ulink> package for | |
available strategies. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>SubclassStrategy</literal>: The default mapping strategy for | |
subclasses. You can specify a builtin strategy alias or the full class name of a | |
<link linkend="ref_guide_mapping_custom_class"> custom class strategy</link>. | |
You can also use OpenJPA's plugin format (see | |
<xref linkend="ref_guide_conf_plugins"/>) to pass arguments to the | |
strategy instance. Common strategies are <literal>vertical</literal> and | |
<literal>flat</literal>, the default. See the | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/strats/package-summary.html"> | |
<literal>org.apache.openjpa.jdbc.meta.strats</literal></ulink> package for all | |
available strategies. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>VersionStrategy</literal>: The default version strategy for classes | |
without a version field. You can specify a builtin strategy alias or the full | |
class name of a <link linkend="ref_guide_mapping_custom_versdiscrim"> custom | |
version strategy</link>. You can also use OpenJPA's plugin format (see | |
<xref linkend="ref_guide_conf_plugins"/>) to pass arguments to the | |
strategy instance. Common strategies are <literal>none</literal>, <literal> | |
state-comparison</literal>, <literal> timestamp</literal>, and <literal> | |
version-number</literal>, the default. See the | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/strats/package-summary.html"> | |
<literal>org.apache.openjpa.jdbc.meta.strats</literal></ulink> package for all | |
available strategies. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>DiscriminatorStrategy</literal>: The default discriminator strategy | |
when no discriminator value is given. You can specify a builtin strategy alias | |
or the full class name of a | |
<link linkend="ref_guide_mapping_custom_versdiscrim"> custom discriminator | |
strategy</link>. You can also use OpenJPA's plugin format (see | |
<xref linkend="ref_guide_conf_plugins"/>) to pass arguments to the | |
strategy instance. Common strategies are <literal>final</literal> for a base | |
class without subclasses, <literal>none</literal> to use joins to subclass | |
tables rather than a discriminator column, and <literal> class-name</literal>, | |
the default. See the | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/strats/package-summary.html"> | |
<literal>org.apache.openjpa.jdbc.meta.strats</literal></ulink> package for all | |
available strategies. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>FieldStrategies</literal>: This property associates field types with | |
custom strategies. The format of this property is similar to that of plugin | |
strings (see <xref linkend="ref_guide_conf_plugins"/> ), without the class | |
name. It is a comma-separated list of key/value pairs, where each key is a | |
possible field type, and each value is itself a plugin string describing the | |
strategy for that type. We present an example below. See | |
<xref linkend="ref_guide_mapping_custom_field"/> for information on custum | |
field strategies. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>ForeignKeyDeleteAction</literal>: The default delete action of foreign | |
keys representing relations to other objects. Recognized values include | |
<literal>restrict</literal>, <literal>cascade</literal>, <literal>null</literal> | |
, <literal>default</literal>. These values correspond exactly to the standard | |
database foreign key actions of the same names. | |
</para> | |
<para> | |
The value <literal>none</literal> tells OpenJPA not to create database foreign | |
keys on relation columns. This is the default. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>JoinForeignKeyDeleteAction</literal>: The defualt delete action of | |
foreign keys that join join secondary, collection, map, or subclass tables to | |
the primary table. Accepts the same values as the <literal> | |
ForeignKeyDeleteAction</literal> property above. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>DeferConstraints</literal>: Whether to use deferred database | |
constraints if possible. Defaults to false. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>IndexLogicalForeignKeys</literal>: Boolean property controlling | |
whether to create indexes on logical foreign keys. Logical foreign keys are | |
columns that represent a link between tables, but have been configured through | |
the <literal>ForeignKey</literal> properties above not to use a physical | |
database foreign key. Defaults to true. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>DataStoreIdColumnName</literal>: The default name of datastore | |
identity columns. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>DiscriminatorColumnName</literal>: The default name of discriminator | |
columns. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>IndexDiscriminator</literal>: Whether to index the discriminator | |
column. Defaults to true. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>VersionColumnName</literal>: The default name of version columns. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>IndexVersion</literal>: Whether to index the version column. Defaults | |
to false. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>AddNullIndicator</literal>: Whether to create a synthetic null | |
indicator column for embedded mappings. The null indicator column allows OpenJPA | |
to distinguish between a null embedded object and one with default values for | |
all persistent fields. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>NullIndicatorColumnName</literal>: The default name of synthetic null | |
indicator columns for embedded objects. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>OrderLists</literal>: Whether to create a database ordering column for | |
maintaining the order of persistent lists and arrays. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>OrderColumnName</literal>: The default name of collection and array | |
ordering columns. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>StoreEnumOrdinal</literal>: Set to true to store enum fields as | |
numeric ordinal values in the database. The default is to store the enum value | |
name as a string, which is more robust if the Java enum declaration might be | |
rearranged. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>StoreUnmappedObjectIdString</literal>: Set to true to store the | |
stringified identity of related objects when the declared related type is | |
unmapped. By default, OpenJPA stores the related object's primary key value(s). | |
However, this breaks down if different subclasses of the related type use | |
incompatible primary key structures. In that case, stringifying the identity | |
value is the better choice. | |
</para> | |
</listitem> | |
</itemizedlist> | |
</listitem> | |
</itemizedlist> | |
<para> | |
The example below turns on foreign key generation during schema creation and | |
associates the <classname>org.mag.data.InfoStruct</classname> field type with | |
the custom <classname>org.mag.mapping.InfoStructHandler</classname> value | |
handler. | |
</para> | |
<example id="ref_guide_mapping_defaults_conf"> | |
<title> | |
Configuring Mapping Defaults | |
</title> | |
<programlisting> | |
<property name="openjpa.jdbc.MappingDefaults" | |
value="ForeignKeyDeleteAction=restrict, | |
FieldStrategies='org.mag.data.InfoStruct=org.mag.mapping.InfoStructHandler'"/> | |
</programlisting> | |
</example> | |
</section> | |
<section id="ref_guide_mapping_factory"> | |
<title> | |
Mapping Factory | |
</title> | |
<indexterm zone="ref_guide_mapping_factory"> | |
<primary> | |
MappingFactory | |
</primary> | |
</indexterm> | |
<indexterm> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
loading and storing | |
</secondary> | |
<see> | |
MappingFactory | |
</see> | |
</indexterm> | |
<para> | |
An important decision in the object-relational mapping process is how and where | |
to store the data necessary to map your persistent classes to the database | |
schema. | |
</para> | |
<para> | |
<xref linkend="ref_guide_meta_factory"/> introduced OpenJPA's <classname> | |
MetaDataFactory</classname> interface. OpenJPA uses this same interface to | |
abstract the storage and retrieval of mapping information. OpenJPA includes the | |
built-in mapping factories below, and you can create your own factory if you | |
have custom needs. You control which mapping factory OpenJPA uses with the | |
<link linkend="openjpa.jdbc.MappingFactory"><literal> | |
openjpa.jdbc.MappingFactory</literal></link> configuration property. | |
</para> | |
<para> | |
The bundled mapping factories are: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>-</literal>: Leaving the <literal> openjpa.jdbc.MappingFactory | |
</literal> property unset allows your metadata factory to take over mappings as | |
well. If you are using the default <literal>jpa</literal> metadata factory, | |
OpenJPA will read mapping information from your annotations and | |
<filename>orm.xml</filename> when you leave the mapping factory unspecified. | |
</para> | |
</listitem> | |
</itemizedlist> | |
<example id="ref_guide_mapping_factory_jpa"> | |
<title> | |
Standard JPA Configuration | |
</title> | |
<para> | |
In the standard JPA configuration, the mapping factory is left unset. | |
</para> | |
<programlisting> | |
<property name="openjpa.MetaDataFactory" value="jpa"/> | |
</programlisting> | |
</example> | |
</section> | |
<section id="ref_guide_mapping_notes_nonstdjoins"> | |
<title> | |
Non-Standard Joins | |
</title> | |
<indexterm zone="ref_guide_mapping_notes_nonstdjoins"> | |
<primary> | |
joins | |
</primary> | |
<secondary> | |
non-standard | |
</secondary> | |
</indexterm> | |
<para> | |
The JPA Overview's <xref linkend="jpa_overview_mapping"/> explains join | |
mapping. All of the examples in that document, however, use "standard" joins, in | |
that there is one foreign key column for each primary key column in the target | |
table. OpenJPA supports additional join patterns, including partial primary key | |
joins, non-primary key joins, and joins using constant values. | |
</para> | |
<para> | |
<indexterm> | |
<primary> | |
joins | |
</primary> | |
<secondary> | |
partial primary key | |
</secondary> | |
</indexterm> | |
In a partial primary key join, the source table only has foreign key columns for | |
a subset of the primary key columns in the target table. So long as this subset | |
of columns correctly identifies the proper row(s) in the referenced table, | |
OpenJPA will function properly. There is no special syntax for expressing a | |
partial primary key join - just do not include column definitions for missing | |
foreign key columns. | |
</para> | |
<para> | |
<indexterm> | |
<primary> | |
joins | |
</primary> | |
<secondary> | |
non-primary key | |
</secondary> | |
</indexterm> | |
In a non-primary key join, at least one of the target columns is not a primary | |
key. Once again, OpenJPA supports this join type with the same syntax as a | |
primary key join. There is one restriction, however: each non-primary key column | |
you are joining to must be controlled by a field mapping that implements the | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/Joinable.html"><classname> | |
org.apache.openjpa.jdbc.meta.Joinable</classname></ulink> interface. All built | |
in basic mappings implement this interface, including basic fields of embedded | |
objects. OpenJPA will also respect any custom mappings that implement this | |
interface. See <xref linkend="ref_guide_mapping_custom"/> for an | |
examination of custom mappings. | |
</para> | |
<para> | |
<indexterm> | |
<primary> | |
joins | |
</primary> | |
<secondary> | |
constant | |
</secondary> | |
</indexterm> | |
Not all joins consist of only links between columns. In some cases you might | |
have a schema in which one of the join criteria is that a column in the source | |
or target table must have some constant value. OpenJPA calls joins involving | |
constant values <emphasis>constant joins</emphasis>. | |
</para> | |
<para> | |
To form a constant join in JPA mapping, first set the <literal>JoinColumn | |
</literal>'s <literal>name</literal> attribute to the name of the column. If the | |
column with the constant value is the target of the join, give its fully | |
qualified name in the form <literal><table name>.<column name> | |
</literal>. Next, set the <literal>referencedColumnName</literal> attribute to | |
the constant value. If the constant value is a string, place it in single quotes | |
to differentiate it from a column name. | |
</para> | |
<mediaobject> | |
<imageobject> | |
<!-- PNG image data, 427 x 211 (see README) --> | |
<imagedata fileref="img/joins-constant.png" width="285px"/> | |
</imageobject> | |
</mediaobject> | |
<para> | |
Consider the tables above. First, we want to join row <literal>T1.R1</literal> | |
to row <literal>T2.R1</literal>. If we just join column <literal>T1.FK</literal> | |
to <literal>T2.PK1</literal>, we will wind up matching both <literal>T2.R1 | |
</literal> and <literal> T2.R2</literal>. So in addition to joining <literal> | |
T1.FK</literal> to <literal>T2.PK1</literal>, we also have to specify that | |
<literal>T2.PK2</literal> has the value <literal>a</literal>. Here is how we'd | |
accomplish this in mapping metadata. | |
</para> | |
<programlisting> | |
@Entity | |
@Table(name="T1") | |
public class ... { | |
@ManyToOne | |
@JoinColumns({ | |
@JoinColumn(name="FK" referencedColumnName="PK1"), | |
@JoinColumn(name="T2.PK2" referencedColumnName="'a'") | |
}); | |
private ...; | |
} | |
</programlisting> | |
<para> | |
Notice that we had to fully qualify the name of column <literal>PK2</literal> | |
because it is in the target table. Also notice that we put single quotes around | |
the constant value so that it won't be confused with a column name. You do not | |
need single quotes for numeric constants. For example, the syntax to join | |
<literal>T1.R2</literal> to <literal>T2.R4</literal> is: | |
</para> | |
<programlisting> | |
@Entity | |
@Table(name="T1") | |
public class ... { | |
@ManyToOne | |
@JoinColumns({ | |
@JoinColumn(name="FK" referencedColumnName="PK2"), | |
@JoinColumn(name="T2.PK1" referencedColumnName="2") | |
}); | |
private ...; | |
} | |
</programlisting> | |
<para> | |
Finally, from the inverse direction, these joins would look like this: | |
</para> | |
<programlisting> | |
@Entity | |
@Table(name="T2") | |
public class ... { | |
@ManyToOne | |
@JoinColumns({ | |
@JoinColumn(name="T1.FK" referencedColumnName="PK1"), | |
@JoinColumn(name="PK2" referencedColumnName="'a'") | |
}); | |
private ...; | |
@ManyToOne | |
@JoinColumns({ | |
@JoinColumn(name="T1.FK" referencedColumnName="PK2"), | |
@JoinColumn(name="PK1" referencedColumnName="2") | |
}); | |
private ...; | |
} | |
</programlisting> | |
</section> | |
<section id="ref_guide_mapping_jpa"> | |
<title> | |
Additional JPA Mappings | |
</title> | |
<indexterm zone="ref_guide_mapping_jpa"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
JPA additions | |
</secondary> | |
</indexterm> | |
<para> | |
OpenJPA supports many persistence strategies beyond those of the JPA | |
specification. <xref linkend="ref_guide_meta_jpa"/> covered the logical | |
metadata for OpenJPA's additional persistence strategies. We now demonstrate how | |
to map entities using these strategies to the database. | |
</para> | |
<section id="ref_guide_mapping_jpa_datastoreid"> | |
<title> | |
Datastore Identity Mapping | |
</title> | |
<indexterm zone="ref_guide_mapping_jpa_datastoreid"> | |
<primary> | |
datastore identity | |
</primary> | |
<secondary> | |
mapping | |
</secondary> | |
</indexterm> | |
<indexterm zone="ref_guide_mapping_jpa_datastoreid"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
datastore identity | |
</secondary> | |
<seealso> | |
identity | |
</seealso> | |
</indexterm> | |
<indexterm zone="ref_guide_mapping_jpa_datastoreid"> | |
<primary> | |
DataStoreIdColumn | |
</primary> | |
<seealso> | |
mapping metadata | |
</seealso> | |
</indexterm> | |
<indexterm> | |
<primary> | |
primary key | |
</primary> | |
</indexterm> | |
<para> | |
<xref linkend="ref_guide_pc_oid"/> describes how to use datastore identity | |
in JPA. OpenJPA requires a single numeric primary key column to hold datastore | |
identity values. The | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/DataStoreIdColumn.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.DataStoreIdColumn</classname> | |
</ulink> annotation customizes the datastore identity column. This annotation | |
has the following properties: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>String name</literal>: Defaults to <literal>ID</literal>. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>int precision</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>String columnDefinition</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>boolean insertable</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>boolean updatable</literal> | |
</para> | |
</listitem> | |
</itemizedlist> | |
<para> | |
All properties correspond exactly to the same-named properties on the standard | |
<classname>Column</classname> annotation, described in | |
<xref linkend="jpa_overview_mapping_column"/>. | |
</para> | |
<example id="ref_guide_mapping_jpa_datastoreidex"> | |
<title> | |
Datastore Identity Mapping | |
</title> | |
<programlisting> | |
import org.apache.openjpa.persistence.*; | |
import org.apache.openjpa.persistence.jdbc.*; | |
@Entity | |
@Table(name="LOGS") | |
@DataStoreIdColumn(name="ENTRY") | |
public class LogEntry { | |
@Lob | |
private String content; | |
... | |
} | |
</programlisting> | |
</example> | |
</section> | |
<section id="ref_guide_mapping_jpa_version"> | |
<title> | |
Surrogate Version Mapping | |
</title> | |
<indexterm zone="ref_guide_mapping_jpa_datastoreid"> | |
<primary> | |
version | |
</primary> | |
<secondary> | |
mapping | |
</secondary> | |
</indexterm> | |
<indexterm zone="ref_guide_mapping_jpa_version"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
version | |
</secondary> | |
<seealso> | |
version | |
</seealso> | |
</indexterm> | |
<indexterm zone="ref_guide_mapping_jpa_version"> | |
<primary> | |
VersionColumn | |
</primary> | |
<seealso> | |
mapping metadata | |
</seealso> | |
</indexterm> | |
<para> | |
OpenJPA supports version fields as defined by the JPA specification, but allows | |
you to use a surrogate version column in place of a version field if you like. | |
You map the surrogate version column with the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/VersionColumn.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.VersionColumn</classname></ulink> | |
annotation. You can also use the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/VersionColumns.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.VersionColumns</classname> | |
</ulink> annotation to declare an array of <classname>VersionColumn</classname> | |
values. Each <classname>VersionColumn</classname> has the following properties: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>String name</literal>: Defaults to <literal>VERSN</literal>. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>int length</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>int precision</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>int scale</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>String columnDefinition</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>boolean nullable</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>boolean insertable</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>boolean updatable</literal> | |
</para> | |
</listitem> | |
</itemizedlist> | |
<para> | |
All properties correspond exactly to the same-named properties on the standard | |
<classname>Column</classname> annotation, described in | |
<xref linkend="jpa_overview_mapping_column"/>. | |
</para> | |
<para> | |
By default, OpenJPA assumes that surrogate versioning uses a version number | |
strategy. You can choose a different strategy with the <classname> | |
VersionStrategy</classname> annotation described in | |
<xref linkend="version-strategy"/>. | |
</para> | |
</section> | |
<section id="ref_guide_mapping_jpa_columns"> | |
<title> | |
Multi-Column Mappings | |
</title> | |
<indexterm zone="ref_guide_mapping_jpa_columns"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
column | |
</secondary> | |
</indexterm> | |
<indexterm zone="ref_guide_mapping_jpa_columns"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
multi-column mappings | |
</secondary> | |
</indexterm> | |
<indexterm zone="ref_guide_mapping_jpa_columns"> | |
<primary> | |
Columns | |
</primary> | |
<seealso> | |
mapping metadata | |
</seealso> | |
</indexterm> | |
<para> | |
OpenJPA makes it easy to create multi-column | |
<link linkend="ref_guide_mapping_custom_field">custom mappings</link>. The JPA | |
specification includes a <classname>Column</classname> annotation, but is | |
missing a way to declare multiple columns for a single field. OpenJPA remedies | |
this with the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Columns.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.Columns</classname></ulink> | |
annotation, which contains an array of <classname>Column</classname> values. | |
</para> | |
<para> | |
Remember to annotate custom field types with <classname>Persistent</classname>, | |
as described in <xref linkend="ref_guide_meta_jpa_persistent"/>. | |
</para> | |
</section> | |
<section id="ref_guide_mapping_jpa_fieldjoin"> | |
<title> | |
Join Column Attribute Targets | |
</title> | |
<para> | |
<xref linkend="jpa_overview_mapping_rel"/> in the JPA Overview introduced | |
you to the <classname>JoinColumn</classname> annotation. A <classname> | |
JoinColumn</classname>'s <literal> referencedColumnName</literal> property | |
declares which column in the table of the related type this join column links | |
to. Suppose, however, that the related type is unmapped, or that it is part of a | |
table-per-class inheritance hierarchy. Each subclass that might be assigned to | |
the field could reside in a different table, and could use entirely different | |
names for its primary key columns. It becomes impossible to supply a single | |
<literal>referencedColumnName</literal> that works for all subclasses. | |
</para> | |
<para> | |
OpenJPA rectifies this by allowing you to declare which <emphasis>attribute | |
</emphasis> in the related type each join column links to, rather than which | |
column. If the attribute is mapped differently in various subclass tables, | |
OpenJPA automatically forms the proper join for the subclass record at hand. The | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/XJoinColumn.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.XJoinColumn</classname></ulink> | |
annotation has all the same properties as the standard <classname>JoinColumn | |
</classname> annotation, but adds an additional <literal> | |
referencedAttributeName</literal> property for this purpose. Simply use a | |
<classname>XJoinColumn</classname> in place of a <classname>JoinColumn | |
</classname> whenever you need to access this added functionality. | |
</para> | |
<para> | |
For compound keys, use the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/XJoinColumns.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.XJoinColumns</classname></ulink> | |
annotation. The value of this annotation is an array of individual <classname> | |
XJoinColumn</classname>s. | |
</para> | |
</section> | |
<section id="ref_guide_mapping_jpa_embed"> | |
<title> | |
Embedded Mapping | |
</title> | |
<para> | |
JPA uses the <classname>AttributeOverride</classname> annotation to override the | |
default mappings of an embeddable class. The JPA Overview details this process | |
in <xref linkend="jpa_overview_mapping_embed"/>. <classname> | |
AttributeOverride</classname>s suffice for simple mappings, but do not allow | |
you to override complex mappings. Also, JPA has no way to differentitate between | |
a null embedded object and one with default values for all of its fields. | |
</para> | |
<para> | |
OpenJPA overcomes these shortcomings with the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/EmbeddedMapping.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.EmbeddedMapping</classname> | |
</ulink> annotation. This annotation has the following properties: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>String nullIndicatorColumnName</literal>: If the named column's value | |
is <literal>NULL</literal>, then the embedded object is assumed to be null. If | |
the named column has a non- <literal>NULL</literal> value, then the embedded | |
object will get loaded and populated with data from the other embedded fields. | |
This property is entirely optional. By default, OpenJPA always assumes the | |
embedded object is non-null, just as in standard JPA mapping. | |
</para> | |
<para> | |
If the column you name does not belong to any fields of the embedded object, | |
OpenJPA will create a synthetic null-indicator column with this name. In fact, | |
you can specify a value of <literal>true</literal> to simply indicate that you | |
want a synthetic null-indicator column, without having to come up with a name | |
for it. A value of <literal>false</literal> signals that you explicitly do not | |
want a null-indicator column created for this mapping (in case you have | |
configured your <link linkend="ref_guide_mapping_defaults">mapping defaults | |
</link> to create one by default). | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>String nullIndicatorFieldName</literal>: Rather than name a null | |
indicator column, you can name a field of the embedded type. OpenJPA will use | |
the column of this field as the null-indicator column. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>MappingOverride[] overrides</literal>: This array allows you to | |
override any mapping of the embedded object. | |
</para> | |
</listitem> | |
</itemizedlist> | |
<para> | |
The <classname>EmbeddedMapping</classname>'s <literal>overrides</literal> array | |
serves the same purpose as standard JPA's <classname>AttributeOverride | |
</classname>s and <classname>AssociationOverride</classname> s. In fact, you can | |
also use the <classname>MappingOverride</classname> annotation on an entity | |
class to override a complex mapping of its mapped superclass, just as you can | |
with <classname> AttributeOverride</classname> and <classname> | |
AssociationOverride</classname> s. The <classname>MappingOverrides</classname> | |
annotation, whose value is an array of <classname>MappingOverride</classname> s, | |
allows you to overide multiple mapped superclass mappings. | |
</para> | |
<para> | |
Each | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/MappingOverride.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.MappingOverride</classname> | |
</ulink> annotation has the following properties: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>String name</literal>: The name of the field that is being overridden. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>Column[] columns</literal>: Columns for the new field mapping. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>XJoinColumn[] joinColumns</literal>: Join columns for the new field | |
mapping, if it is a relation field. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>ContainerTable containerTable</literal>: Table for the new collection | |
or map field mapping. We cover collection mappings in | |
<xref linkend="ref_guide_mapping_jpa_coll"/>, and map mappings in | |
<xref linkend="ref_guide_mapping_jpa_map"/>. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>ElementJoinColumn[] elementJoinColumns</literal>: Element join columns | |
for the new collection or map field mapping. You will see how to use element | |
join columns in <xref linkend="ref_guide_mapping_jpa_coll_joincols"/>. | |
</para> | |
</listitem> | |
</itemizedlist> | |
<para> | |
The following example defines an embeddable <classname> PathCoordinate | |
</classname> class with a custom mapping of a <classname>java.awt.Point | |
</classname> field to two columns. It then defines an entity which embeds a | |
<classname> PointCoordinate</classname> and overrides the default mapping for | |
the point field. The entity also declares that if the <classname>PathCoordinate | |
</classname>'s <literal>siteName</literal> field column is null, it means that | |
no <classname>PathCoordinate</classname> is stored in the embedded record; the | |
owning field will load as null. | |
</para> | |
<example id="ref_guide_mapping_jpa_embedex"> | |
<title> | |
Overriding Complex Mappings | |
</title> | |
<programlisting> | |
import org.apache.openjpa.persistence.jdbc.*; | |
@Embeddable | |
public class PathCoordinate { | |
private String siteName; | |
@Persistent | |
@Strategy("com.xyz.openjpa.PointValueHandler") | |
private Point point; | |
... | |
} | |
@Entity | |
public class Path { | |
@Embedded | |
@EmbeddedMapping(nullIndicatorFieldName="siteName", overrides={ | |
@MappingOverride(name="siteName", columns=@Column(name="START_SITE")), | |
@MappingOverride(name="point", columns={ | |
@Column(name="START_X"), | |
@Column(name="START_Y") | |
}) | |
}) | |
private PathCoordinate start; | |
... | |
} | |
</programlisting> | |
</example> | |
</section> | |
<section id="ref_guide_mapping_jpa_coll"> | |
<title> | |
Collections | |
</title> | |
<indexterm zone="ref_guide_mapping_jpa_coll"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
collections | |
</secondary> | |
</indexterm> | |
<para> | |
In <xref linkend="ref_guide_meta_jpa_persistent_coll"/>, we explored the | |
<classname>PersistentCollection</classname> annotation for persistent collection | |
fields that aren't a standard <literal>OneToMany</literal> or <literal> | |
ManyToMany</literal> relation. To map these non-standard collections, combine | |
OpenJPA's <classname>ContainerTable</classname> annotation with | |
<classname>ElementJoinColumn</classname>s. | |
We explore the annotations below. | |
</para> | |
<section id="ref_guide_mapping_jpa_coll_table"> | |
<title> | |
Container Table | |
</title> | |
<indexterm zone="ref_guide_mapping_jpa_coll_table"> | |
<primary> | |
ContainerTable | |
</primary> | |
<seealso> | |
mapping metadata | |
</seealso> | |
</indexterm> | |
<para> | |
The | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ContainerTable.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.ContainerTable</classname> | |
</ulink> annotation describes a database table that holds collection (or map) | |
elements. This annotation has the following properties: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>String name</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>String catalog</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>String schema</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>XJoinColumn[] joinColumns</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>ForeignKey joinForeignKey</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>Index joinIndex</literal> | |
</para> | |
</listitem> | |
</itemizedlist> | |
<para> | |
The <literal>name</literal>, <literal>catalog</literal>, <literal>schema | |
</literal>, and <literal>joinColumns</literal> properties describe the container | |
table and how it joins to the owning entity's table. These properties correspond | |
to the same-named properties on the standard <classname> JoinTable</classname> | |
annotation, described in <xref linkend="jpa_overview_mapping_assoccoll"/> | |
. If left unspecified, the name of the table defaults to the first five | |
characters of the entity table name, plus an underscore, plus the field name. | |
The <literal>joinForeignKey</literal> and <literal> joinIndex</literal> | |
properties override default foreign key and index generation for the join | |
columns. We explore foreign keys and indexes later in this chapter. | |
</para> | |
<para> | |
You may notice that the container table does not define how to store the | |
collection elements. That is left to separate annotations, which are the subject | |
of the next sections. | |
</para> | |
</section> | |
<section id="ref_guide_mapping_jpa_coll_joincols"> | |
<title> | |
Element Join Columns | |
</title> | |
<indexterm zone="ref_guide_mapping_jpa_coll_joincols"> | |
<primary> | |
ElementJoinColumn | |
</primary> | |
<seealso> | |
mapping metadata | |
</seealso> | |
</indexterm> | |
<para> | |
Element join columns are equivalent to standard JPA join columns, except that | |
they represent a join to a collection or map element entity rather than a direct | |
relation. You represent an element join column with OpenJPA's | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementJoinColumn.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.ElementJoinColumn</classname> | |
</ulink> annotation. To declare a compound join, enclose an array of <classname> | |
ElementJoinColumn</classname>s in the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementJoinColumns.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.ElementJoinColumns</classname> | |
</ulink> annotation. | |
</para> | |
<para> | |
An <classname>ElementJoinColumn</classname> always resides in a container table, | |
so it does not have the <literal> table</literal> property of a standard | |
<classname> JoinColumn</classname>. Like <classname> XJoinColumn</classname>s | |
above, <classname> ElementJoinColumn</classname>s can reference a linked | |
attribute rather than a static linked column. Otherwise, the <classname> | |
ElementJoinColumn</classname> and standard <classname>JoinColumn</classname> | |
annotations are equivalent. See <xref linkend="jpa_overview_mapping_rel"/> | |
in the JPA Overview for a review of the <classname>JoinColumn</classname> | |
annotation. | |
</para> | |
</section> | |
<section id="ref_guide_mapping_jpa_coll_order"> | |
<title> | |
Order Column | |
</title> | |
<indexterm zone="ref_guide_mapping_jpa_coll_order"> | |
<primary> | |
OrderColumn | |
</primary> | |
<seealso> | |
mapping metadata | |
</seealso> | |
</indexterm> | |
<para> | |
Relational databases do not guarantee that records are returned in insertion | |
order. If you want to make sure that your collection elements are loaded in the | |
same order they were in when last stored, you must declare an order column. | |
OpenJPA's | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/OrderColumn"> | |
<classname>org.apache.openjpa.persistence.jdbc.OrderColumn</classname></ulink> | |
annotation has the following properties: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>String name</literal>: Defaults to <literal>ORDR</literal>. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>boolean enabled</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>int precision</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>String columnDefinition</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>boolean insertable</literal> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>boolean updatable</literal> | |
</para> | |
</listitem> | |
</itemizedlist> | |
<para> | |
Order columns are always in the container table. You can explicitly turn off | |
ordering (if you have enabled it by default via your | |
<link linkend="ref_guide_mapping_defaults"> mapping defaults</link>) by setting | |
the <literal>enabled</literal> property to <literal>false</literal>. All other | |
properties correspond exactly to the same-named properties on the standard | |
<classname>Column</classname> annotation, described in | |
<xref linkend="jpa_overview_mapping_column"/>. | |
</para> | |
</section> | |
</section> | |
<section id="ref_guide_mapping_jpa_onemany"> | |
<title> | |
One-Sided One-Many Mapping | |
</title> | |
<indexterm zone="ref_guide_mapping_jpa_onemany"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
collections | |
</secondary> | |
<tertiary> | |
JPA one-sided one-many | |
</tertiary> | |
</indexterm> | |
<para> | |
The previous section covered the use of <classname>ElementJoinColumn</classname> | |
annotations in conjunction with a <classname>ContainerTable</classname> for | |
mapping collections to dedicate tables. <classname>ElementJoinColumn</classname> | |
s, however, have one additional use: to create a one-sided one-many mapping. | |
Standard JPA supports <classname>OneToMany</classname> fields without a | |
<literal>mappedBy</literal> inverse, but only by mapping these fields to a | |
<classname>JoinTable</classname> (see | |
<xref linkend="jpa_overview_mapping_assoccoll"/> in the JPA Overview for | |
details). Often, you'd like to create a one-many association based on an inverse | |
foreign key (logical or actual) in the table of the related type. | |
</para> | |
<mediaobject> | |
<imageobject> | |
<!-- PNG image data, 392 x 192 (see README) --> | |
<imagedata fileref="img/inv-key-coll.png" width="261"/> | |
</imageobject> | |
</mediaobject> | |
<para> | |
Consider the model above. <classname>Subscription</classname> has a collection | |
of <classname>LineItem</classname> s, but <classname>LineItem</classname> has | |
no inverse relation to <classname>Subscription</classname>. To retrieve all of | |
the <classname>LineItem</classname> records for a <classname>Subscription | |
</classname>, we join the <literal>SUB_ID</literal> inverse foreign key column | |
in the <literal>LINE_ITEM</literal> table to the primary key column of the | |
<literal>SUB</literal> table. The example below shows how to represent this | |
model in mapping annotations. Note that OpenJPA automatically assumes an inverse | |
foreign key mapping when element join columns are given, but no container or | |
join table is given. | |
</para> | |
<example id="ref_guide_mapping_jpa_onemanyex"> | |
<title> | |
One-Sided One-Many Mapping | |
</title> | |
<programlisting> | |
package org.mag.subscribe; | |
import org.apache.openjpa.persistence.jdbc.*; | |
@Entity | |
@Table(name="LINE_ITEM", schema="CNTRCT") | |
public class LineItem { | |
... | |
} | |
@Entity | |
@Table(name="SUB", schema="CNTRCT") | |
public class Subscription { | |
@Id private long id; | |
@OneToMany | |
@ElementJoinColumn(name="SUB_ID", target="ID") | |
private Collection<LineItem> items; | |
... | |
} | |
</programlisting> | |
</example> | |
</section> | |
<section id="ref_guide_mapping_jpa_map"> | |
<title> | |
Maps | |
</title> | |
<indexterm zone="ref_guide_mapping_jpa_map"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
maps | |
</secondary> | |
</indexterm> | |
<para> | |
We detailed the <literal>ContainerTable</literal> annotation in | |
<xref linkend="ref_guide_mapping_jpa_coll_table"/>. Custom map mappings may | |
also use this annotation to represent a map table. | |
</para> | |
</section> | |
<section id="ref_guide_mapping_jpa_constraints"> | |
<title> | |
Indexes and Constraints | |
</title> | |
<para> | |
OpenJPA uses index information during schema generation to index the proper | |
columns. OpenJPA uses foreign key and unique constraint information during | |
schema creation to generate the proper database constraints, and also at runtime | |
to order SQL statements to avoid constraint violations while maximizing SQL | |
batch size. | |
</para> | |
<para> | |
OpenJPA assumes certain columns have indexes or constraints based on your | |
mapping defaults, as detailed in <xref linkend="ref_guide_mapping_defaults"/>. | |
You can override the configured defaults on individual joins, field | |
values, collection elements, map keys, or map values using the annotations | |
presented in the following sections. | |
</para> | |
<section id="ref_guide_mapping_jpa_index"> | |
<title> | |
Indexes | |
</title> | |
<indexterm zone="ref_guide_mapping_jpa_index"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
indexes | |
</secondary> | |
</indexterm> | |
<indexterm zone="ref_guide_mapping_jpa_index"> | |
<primary> | |
indexes | |
</primary> | |
</indexterm> | |
<para> | |
The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Index.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.Index</classname></ulink> | |
annotation represents an index on the columns of a field. It is also used within | |
the <link linkend="ref_guide_mapping_jpa_coll_table"><classname>ContainerTable | |
</classname></link> annotation to index join columns. | |
To index the columns of a collection element, use the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementIndex.html"> | |
<classname> org.apache.openjpa.persistence.jdbc.ElementIndex</classname></ulink> | |
annotation. These annotations have the following properties: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>boolean enabled</literal>: Set this property to <literal>false | |
</literal> to explicitly tell OpenJPA not to index these columns, when OpenJPA | |
would otherwise do so. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>String name</literal>: The name of the index. OpenJPA will choose a | |
name if you do not provide one. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>boolean unique</literal>: Whether to create a unique index. Defaults | |
to false. | |
</para> | |
</listitem> | |
</itemizedlist> | |
</section> | |
<section id="ref_guide_mapping_jpa_fk"> | |
<title> | |
Foreign Keys | |
</title> | |
<indexterm zone="ref_guide_mapping_jpa_fk"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
foreign keys | |
</secondary> | |
</indexterm> | |
<indexterm zone="ref_guide_mapping_jpa_fk"> | |
<primary> | |
foreign keys | |
</primary> | |
</indexterm> | |
<para> | |
The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ForeignKey.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.ForeignKey</classname></ulink> | |
annotation represents a foreign key on the columns of a field. It is also used | |
within the <link linkend="ref_guide_mapping_jpa_coll_table"><classname> | |
ContainerTable</classname></link> annotation to set a database foreign key on | |
join columns. To set a constraint to the columns of a collection element, use | |
the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementForeignKey.html"> | |
<classname> org.apache.openjpa.persistence.jdbc.ElementForeignKey</classname> | |
</ulink> annotation. These annotations have the following properties: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>boolean enabled</literal>: Set this property to <literal>false | |
</literal> to explicitly tell OpenJPA not to set a foreign key on these columns, | |
when OpenJPA would otherwise do so. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>String name</literal>: The name of the foreign key. OpenJPA will | |
choose a name if you do not provide one, or will create an anonymous key. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>boolean deferred</literal>: Whether to create a deferred key if | |
supported by the database. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>ForeignKeyAction deleteAction</literal>: Value from the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ForeignKeyAction.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.ForeignKeyAction</classname> | |
</ulink> enum identifying the desired delete action. Defaults to <literal> | |
RESTRICT</literal>. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>ForeignKeyAction updateAction</literal>: Value from the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ForeignKeyAction.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.ForeignKeyAction</classname> | |
</ulink> enum identifying the desired update action. Defaults to <literal> | |
RESTRICT</literal>. | |
</para> | |
</listitem> | |
</itemizedlist> | |
<para> | |
Keep in mind that OpenJPA uses foreign key information at runtime to avoid | |
constraint violations; it is important, therefore, that your | |
<link linkend="ref_guide_mapping_defaults">mapping defaults</link> and foreign | |
key annotations combine to accurately reflect your existing database | |
constraints, or that you configure OpenJPA to reflect on your database schema | |
to discover existing foreign keys (see | |
<xref linkend="ref_guide_schema_info_factory"/>). | |
</para> | |
</section> | |
<section id="ref_guide_mapping_jpa_unique"> | |
<title> | |
Unique Constraints | |
</title> | |
<indexterm zone="ref_guide_mapping_jpa_unique"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
unique constraints | |
</secondary> | |
</indexterm> | |
<indexterm zone="ref_guide_mapping_jpa_unique"> | |
<primary> | |
unique constraints | |
</primary> | |
</indexterm> | |
<para> | |
The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Unique.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.Unique</classname></ulink> | |
annotation represents a unqiue constraint on the columns of a field. It is more | |
convenient than using the <literal>uniqueConstraints</literal> property of | |
standard JPA <classname>Table</classname> and <classname>SecondaryTable | |
</classname> annotations, because you can apply it directly to the constrained | |
field. The <classname>Unique</classname> annotation has the following | |
properties: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>boolean enabled</literal>: Set this property to <literal>false | |
</literal> to explicitly tell OpenJPA not to constrain these columns, when | |
OpenJPA would otherwise do so. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>String name</literal>: The name of the constraint. OpenJPA will choose | |
a name if you do not provide one, or will create an anonymous constraint. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>boolean deferred</literal>: Whether to create a deferred constraint if | |
supported by the database. | |
</para> | |
</listitem> | |
</itemizedlist> | |
</section> | |
</section> | |
<section id="ref_guide_xmlmapping"> | |
<title> | |
XML Column Mapping | |
</title> | |
<indexterm zone="ref_guide_xmlmapping"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
xml column mapping | |
</secondary> | |
</indexterm> | |
<indexterm zone="ref_guide_xmlmapping"> | |
<primary> | |
xml mapping column | |
</primary> | |
</indexterm> | |
<para> | |
DB2, Oracle and SQLServer support XML column types and | |
XPath queries and indexes over these columns.OpenJPA supports mapping of an | |
entity property mapped to an XML column. | |
</para> | |
<para> | |
Annotate the entity property using the XMLValueHandler strategy: | |
</para> | |
<programlisting> | |
@Persistent | |
@Strategy("org.apache.openjpa.jdbc.meta.strats.XMLValueHandler") | |
</programlisting> | |
<para> | |
The default fetch type is EAGER but can be changed to LAZY by using: | |
</para> | |
<programlisting> | |
@Persistence(fetch=FetchType.LAZY) | |
</programlisting> | |
<para> | |
The entity property class is required to have | |
jaxb binding annotations. This is produced when the classes are generated | |
from an xml schema using the jaxb generator XJC.Ensure that <classname>@XmlRootElement</classname> | |
appears in the root class. In some case this annotation needs to be added manually if it is missing. | |
</para> | |
<para> | |
The jaxb jar files must be on the application classpath (jaxb-api.jar, | |
jaxb-impl.jar, jsr173_1.0_api.jar or equivalent). | |
</para> | |
<para> | |
EJB Query path expressions can navigate into the mapped class and its | |
subfields to any level. | |
</para> | |
<para> | |
The path expression is rewritten into an equivalent XPATH expression using SQL | |
XML functions. | |
</para> | |
<para> | |
The path expression must be single valued.Path expressions over xml | |
mapped classes can only be used in WHERE as an operand to a simple predicate | |
(= <> < > >= <=). | |
</para> | |
<para> | |
Path expressions over XML mapped fields can not be: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
an input to a EJB query scalar function | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
an operand of BETWEEN, IS NULL, LIKE or IN predicate | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
used to project out subfields in the SELECT clause | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
used in the FROM , GROUP BY, HAVING, ORDER BY clauses | |
</para> | |
</listitem> | |
</itemizedlist> | |
<para> | |
XML schema must not contain namespace declarations. The EJB query path | |
expressions can not refer to java fields generated from XML ANY type or | |
XML mixed element types. | |
</para> | |
<para> | |
The datatype generated by JAXB must be a valid EJB query type | |
to use the property in an EJB query predicate. | |
</para> | |
<para> | |
Shown below is a sample XML schema <link linkend="ref_guide_xmlmapping_myaddress">myaddress.xsd</link>, | |
in which the JPA entity Order has <classname><shipAddress></classname> persistent field that maps to an XML column. | |
</para> | |
<example id="ref_guide_xmlmapping_myaddress"> | |
<title> | |
myaddress.xsd | |
</title> | |
<programlisting> | |
<?xml version="1.0" ?> | |
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" > | |
<xs:complexType name="Address"> | |
<xs:sequence> | |
<xs:element name="Name" type="xs:string" /> | |
<xs:element name="Street" type="xs:string" | |
minOccurs="1" maxOccurs="3" /> | |
<xs:element name="City" type="xs:string" /> | |
</xs:sequence> | |
</xs:complexType> | |
<xs:complexType name="CAN_Address"> | |
<xs:complexContent> | |
<xs:extension base="Address"> | |
<xs:sequence> | |
<xs:element name="Province" type="xs:string" /> | |
<xs:element name="PostalCode" type="xs:string" /> | |
</xs:sequence> | |
</xs:extension> | |
</xs:complexContent> | |
</xs:complexType> | |
<xs:simpleType name="USPS_ZIP"> | |
<xs:restriction base="xs:integer"> | |
<xs:minInclusive value="01000" /> | |
<xs:maxInclusive value="99999" /> | |
</xs:restriction> | |
</xs:simpleType> | |
<xs:complexType name="USA_Address"> | |
<xs:complexContent> | |
<xs:extension base="Address"> | |
<xs:sequence> | |
<xs:element name="State" type="xs:string" /> | |
<xs:element name="ZIP" type="USPS_ZIP" /> | |
</xs:sequence> | |
</xs:extension> | |
</xs:complexContent> | |
</xs:complexType> | |
<xs:element name="MailAddress" type="Address" /> | |
<xs:element name="AddrCAN" type="CAN_Address" | |
substitutionGroup="MailAddress" /> | |
<xs:element name="AddrUSA" type="USA_Address" | |
substitutionGroup="MailAddress" /> | |
</xs:schema> | |
</programlisting> | |
</example> | |
<para> | |
Java classes <link linkend="ref_guide_xmlmapping_address">Address</link>, | |
<link linkend="ref_guide_xmlmapping_usaaddress">USAAddress</link> and | |
<link linkend="ref_guide_xmlmapping_canaddress">CANAddress</link> | |
are produced using jaxb XJC generator from myaddress schema. | |
</para> | |
<example id="ref_guide_xmlmapping_address"> | |
<title> | |
Address.Java | |
</title> | |
<programlisting> | |
... | |
@XmlRootElement | |
@XmlAccessorType(XmlAccessType.FIELD) | |
@XmlType(name = "Address", propOrder = { | |
"name", | |
"street", | |
"city" | |
}) | |
public class Address { | |
@XmlElement(name = "Name", required = true) | |
protected String name; | |
@XmlElement(name = "Street", required = true) | |
protected List<String> street; | |
@XmlElement(name = "City", required = true) | |
protected String city; | |
/** | |
* Getter and Setter methods. | |
* | |
*/ | |
... | |
} | |
</programlisting> | |
</example> | |
<example id="ref_guide_xmlmapping_usaaddress"> | |
<title> | |
USAAddress.java | |
</title> | |
<programlisting> | |
... | |
@XmlRootElement | |
@XmlAccessorType(XmlAccessType.FIELD) | |
@XmlType(name = "USA_Address", propOrder = { | |
"state", | |
"zip" | |
}) | |
public class USAAddress | |
extends Address | |
{ | |
@XmlElement(name = "State") | |
protected String state; | |
@XmlElement(name = "ZIP") | |
protected int zip; | |
/** | |
* Getter and Setter methods. | |
* | |
*/ | |
... | |
} | |
</programlisting> | |
</example> | |
<example id="ref_guide_xmlmapping_canaddress"> | |
<title> | |
CANAddress.java | |
</title> | |
<programlisting> | |
... | |
@XmlRootElement | |
@XmlAccessorType(XmlAccessType.FIELD) | |
@XmlType(name = "CAN_Address", propOrder = { | |
"province", | |
"postalCode" | |
}) | |
public class CANAddress | |
extends Address | |
{ | |
@XmlElement(name = "Province") | |
protected String province; | |
@XmlElement(name = "PostalCode") | |
protected String postalCode; | |
/** | |
* Getter and Setter methods. | |
* | |
*/ | |
... | |
} | |
</programlisting> | |
</example> | |
<example id="ref_guide_xmlmapping_annorder"> | |
<title> | |
Showing annotated Order entity with XML mapping strategy | |
</title> | |
<programlisting> | |
@Entity | |
public class Order { | |
@Id private into id; | |
@Persistent | |
@Strategy ("org.apache.openjpa.jdbc.meta.strats.XMLValueHandler") | |
private Address shipAddress; | |
... | |
} | |
</programlisting> | |
</example> | |
<example id="ref_guide_xmlmapping_createorder"> | |
<title> | |
Showing creation of Order Entity having shipAddress mapped to XML column | |
</title> | |
<programlisting> | |
... | |
myaddress.ObjectFactory addressFactory = new myaddress.ObjectFactory(); | |
Customer c1 = new Customer(); | |
c1.setCid( new Customer.CustomerKey("USA", 1) ); | |
c1.setName("Harry's Auto"); | |
Order o1 = new Order( 850, false, c1); | |
USAAddress addr1 = addressFactory.createUSAAddress(); | |
addr1.setCity("San Jose"); | |
addr1.setState("CA"); | |
addr1.setZIP(new Integer("95141")); | |
addr1.getStreet().add("12500 Monterey"); | |
addr1.setName( c1.getName()); | |
o1.setShipAddress(addr1); | |
em.persist(o1); | |
... | |
</programlisting> | |
</example> | |
<example id="ref_guide_xmlmapping_ejbquery"> | |
<title> | |
Sample EJB Queries for XML Column mapping | |
</title> | |
<programlisting> | |
. select o from Order o where o.shipAddress.city = "San Jose" or | |
o.shipAddress.city = "San Francisco" (OK) | |
. select o.shipaAddress from Order o (OK) | |
. select o.shipAddress.city from Order o (INVALID) | |
. select o from Order o where o.shipAddress.street = "San Jose" (INVALID multi valued) | |
</programlisting> | |
</example> | |
</section> | |
</section> | |
<section id="ref_guide_mapping_limits"> | |
<title> | |
Mapping Limitations | |
</title> | |
<indexterm zone="ref_guide_mapping_limits"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
limitations | |
</secondary> | |
</indexterm> | |
<para> | |
The following sections outline the limitations OpenJPA places on specific | |
mapping strategies. | |
</para> | |
<section id="ref_guide_mapping_limits_tpc"> | |
<title> | |
Table Per Class | |
</title> | |
<indexterm zone="ref_guide_mapping_limits"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
limitations | |
</secondary> | |
<tertiary> | |
table-per-class | |
</tertiary> | |
</indexterm> | |
<para> | |
Table-per-class inheritance mapping has the following limitations: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
You cannot traverse polymorphic relations to non-leaf classes in a | |
table-per-class inheritance hierarchy in queries. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
You cannot map a one-sided polymorphic relation to a non-leaf class in a | |
table-per-class inheritance hierarchy using an inverse foreign key. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
You cannot use an order column in a polymorphic relation to a non-leaf class in | |
a table-per-class inheritance hierarchy mapped with an inverse foreign key. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
Table-per-class hierarchies impose limitations on eager fetching. See | |
<xref linkend="ref_guide_perfpack_eager_consider"/>. | |
</para> | |
</listitem> | |
</itemizedlist> | |
<note> | |
<para> | |
Non-polymorphic relations do not suffer from these limitations. You can declare | |
a non-polymorphic relation using the extensions described in | |
<xref linkend="nonpolymorphic"/>. | |
</para> | |
</note> | |
</section> | |
</section> | |
<section id="ref_guide_mapping_ext"> | |
<title> | |
Mapping Extensions | |
</title> | |
<para> | |
Mapping extensions allow you to access OpenJPA-specific functionality from your | |
mappings. Note that all extensions below are specific to mappings. If you store | |
your mappings separately from your persistence metadata, these extensions must | |
be specified along with the mapping information, not the persistence metadata | |
information. | |
</para> | |
<section id="ref_guide_mapping_ext_cls"> | |
<title> | |
Class Extensions | |
</title> | |
<para> | |
OpenJPA recognizes the following class extensions. | |
</para> | |
<section id="subclass-fetch-mode"> | |
<title> | |
Subclass Fetch Mode | |
</title> | |
<indexterm zone="subclass-fetch-mode"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
extensions | |
</secondary> | |
<tertiary> | |
subclass fetch mode | |
</tertiary> | |
<seealso> | |
eager fetching | |
</seealso> | |
</indexterm> | |
<para> | |
This extension specifies how to eagerly fetch subclass state. It overrides the | |
global <link linkend="openjpa.jdbc.SubclassFetchMode"><literal> | |
openjpa.jdbc.SubclassFetchMode</literal></link> property. Set the JPA | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/SubclassFetchMode.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.SubclassFetchMode</classname> | |
</ulink> annotation to a value from the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/EagerFetchType.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.EagerFetchType</classname> | |
</ulink> enum: <literal>JOIN</literal>, <literal>PARALLEL</literal>, or | |
<literal>NONE</literal>. See <xref linkend="ref_guide_perfpack_eager"/> | |
for a discussion of eager fetching. | |
</para> | |
</section> | |
<section id="class-strategy"> | |
<title> | |
Strategy | |
</title> | |
<indexterm zone="strategy"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
extensions | |
</secondary> | |
<tertiary> | |
strategy | |
</tertiary> | |
<seealso> | |
custom mapping | |
</seealso> | |
</indexterm> | |
<para> | |
The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Strategy.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.Strategy</classname></ulink> | |
class annotation allows you to specify a custom mapping strategy for your class. | |
See <xref linkend="ref_guide_mapping_custom"/> for information on custom | |
mappings. | |
</para> | |
</section> | |
<section id="discriminator-strategy"> | |
<title> | |
Discriminator Strategy | |
</title> | |
<indexterm zone="strategy"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
extensions | |
</secondary> | |
<tertiary> | |
discriminator strategy | |
</tertiary> | |
<seealso> | |
custom mapping | |
</seealso> | |
</indexterm> | |
<para> | |
The | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/DiscriminatorStrategy.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.DiscriminatorStrategy</classname> | |
</ulink> class annotation allows you to specify a custom discriminator strategy. | |
See <xref linkend="ref_guide_mapping_custom"/> for information on custom | |
mappings. | |
</para> | |
</section> | |
<section id="version-strategy"> | |
<title> | |
Version Strategy | |
</title> | |
<indexterm zone="strategy"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
extensions | |
</secondary> | |
<tertiary> | |
version strategy | |
</tertiary> | |
<seealso> | |
custom mapping | |
</seealso> | |
</indexterm> | |
<para> | |
The | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/VersionStrategy.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.VersionStrategy</classname> | |
</ulink> class annotation allows you to specify a custom version strategy. See | |
<xref linkend="ref_guide_mapping_custom"/> for information on custom | |
mappings. | |
</para> | |
</section> | |
</section> | |
<section id="ref_guide_mapping_ext_field"> | |
<title> | |
Field Extensions | |
</title> | |
<para> | |
OpenJPA recognizes the following field extensions. | |
</para> | |
<section id="eager-fetch-mode"> | |
<title> | |
Eager Fetch Mode | |
</title> | |
<indexterm zone="eager-fetch-mode"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
extensions | |
</secondary> | |
<tertiary> | |
eager fetch mode | |
</tertiary> | |
<seealso> | |
eager fetching | |
</seealso> | |
</indexterm> | |
<para> | |
This extension specifies how to eagerly fetch related objects. It overrides the | |
global <link linkend="openjpa.jdbc.EagerFetchMode"><literal> | |
openjpa.jdbc.EagerFetchMode</literal></link> property. Set the JPA | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/EagerFetchMode.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.EagerFetchMode</classname> | |
</ulink> annotation to a value from the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/EagerFetchType.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.EagerFetchType</classname> | |
</ulink> enum: <literal>JOIN</literal>, <literal>PARALLEL</literal>, or | |
<literal>NONE</literal>. See <xref linkend="ref_guide_perfpack_eager"/> | |
for a discussion of eager fetching. | |
</para> | |
</section> | |
<section id="nonpolymorphic"> | |
<title> | |
Nonpolymorphic | |
</title> | |
<indexterm zone="nonpolymorphic"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
extensions | |
</secondary> | |
<tertiary> | |
nonpolymorphic | |
</tertiary> | |
</indexterm> | |
<para> | |
All fields in Java are polymorphic. If you declare a field of type <literal>T | |
</literal>, you can assign any subclass of <literal>T</literal> to the field as | |
well. This is very convenient, but can make relation traversal very inefficient | |
under some inheritance strategies. It can even make querying across the field | |
impossible. Often, you know that certain fields do not need to be entirely | |
polymorphic. By telling OpenJPA about such fields, you can improve the | |
efficiency of your relations. | |
</para> | |
<note> | |
<para> | |
OpenJPA also includes the <literal>type</literal> metadata extension for | |
narrowing the declared type of a field. See <xref linkend="type"/>. | |
</para> | |
</note> | |
<para> | |
OpenJPA defines the following extensions for nonpolymorphic values: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Nonpolymorphic.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.Nonpolymorphic</classname> | |
</ulink> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementNonpolymorphic.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.ElementNonpolymorphic</classname> | |
</ulink> | |
</para> | |
</listitem> | |
</itemizedlist> | |
<para> | |
The value of these extensions is a constant from the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/NonpolymorphicType.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.NonpolymorphicType</classname> | |
</ulink> enumeration. The default value, <literal>EXACT</literal>, indicates | |
that the relation will always be of the exact declared type. A value of | |
<literal>JOINABLE</literal>, on the other hand, means that the relation might | |
be to any joinable subclass of the declared type. This value only excludes | |
table-per-class subclasses. | |
</para> | |
</section> | |
<section id="class-criteria"> | |
<title> | |
Class Criteria | |
</title> | |
<indexterm zone="eager-fetch-mode"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
extensions | |
</secondary> | |
<tertiary> | |
class criteria | |
</tertiary> | |
<seealso> | |
joins | |
</seealso> | |
</indexterm> | |
<indexterm zone="eager-fetch-mode"> | |
<primary> | |
joins | |
</primary> | |
<secondary> | |
class criteria | |
</secondary> | |
</indexterm> | |
<para> | |
This family of boolean extensions determines whether OpenJPA will use the | |
expected class of related objects as criteria in the SQL it issues to load a | |
relation field. Typically, this is not needed. The foreign key values uniquely | |
identify the record for the related object. Under some rare mappings, however, | |
you may need to consider both foreign key values and the expected class of the | |
related object - for example, if you have an inverse relation that shares the | |
foreign key with another inverse relation to an object of a different subclass. | |
In these cases, set the proper class critera extension to <literal>true | |
</literal> to force OpenJPA to append class criteria to its select SQL. | |
</para> | |
<para> | |
OpenJPA defines the following class criteria annotations for field relations and | |
array or collection element relations, respectively: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ClassCriteria.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.ClassCriteria</classname></ulink> | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/ElementClassCriteria.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.ElementClassCriteria</classname> | |
</ulink> | |
</para> | |
</listitem> | |
</itemizedlist> | |
</section> | |
<section id="strategy"> | |
<title> | |
Strategy | |
</title> | |
<indexterm zone="strategy"> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
extensions | |
</secondary> | |
<tertiary> | |
strategy | |
</tertiary> | |
<seealso> | |
custom mapping | |
</seealso> | |
</indexterm> | |
<para> | |
OpenJPA's | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Strategy.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.Strategy</classname></ulink> | |
extension allows you to specify a custom mapping | |
strategy or value handler for a field. See | |
<xref linkend="ref_guide_mapping_custom"/> for information on custom | |
mappings. | |
</para> | |
</section> | |
</section> | |
</section> | |
<section id="ref_guide_mapping_custom"> | |
<title> | |
Custom Mappings | |
</title> | |
<indexterm zone="ref_guide_mapping_custom"> | |
<primary> | |
custom mapping | |
</primary> | |
</indexterm> | |
<indexterm> | |
<primary> | |
mapping metadata | |
</primary> | |
<secondary> | |
custom mapping | |
</secondary> | |
<see> | |
custom mapping | |
</see> | |
</indexterm> | |
<para> | |
In OpenJPA, you are not limited to the set of standard mappings defined by the | |
specification. OpenJPA allows you to define custom class, discriminator, | |
version, and field mapping strategies with all the power of OpenJPA's built-in | |
strategies. | |
</para> | |
<section id="ref_guide_mapping_custom_class"> | |
<title> | |
Custom Class Mapping | |
</title> | |
<para> | |
To create a custom class mapping, write an implementation of the | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ClassStrategy.html"> | |
<classname>org.apache.openjpa.jdbc.meta.ClassStrategy</classname></ulink> | |
interface. You will probably want to extend one of the existing abstract or | |
concrete strategies in the <literal>org.apache.openjpa.jdbc.meta.strats | |
</literal> package. | |
</para> | |
<para> | |
The <ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Strategy.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.Strategy</classname></ulink> | |
annotation allows you to declare a custom class mapping strategy in JPA mapping | |
metadata. Set the value of the annotation to the full class name of your custom | |
strategy. You can configure your strategy class' bean properties using | |
OpenJPA's plugin syntax, detailed in <xref linkend="ref_guide_conf_plugins"/>. | |
</para> | |
</section> | |
<section id="ref_guide_mapping_custom_versdiscrim"> | |
<title> | |
Custom Discriminator and Version Strategies | |
</title> | |
<para> | |
To define a custom discriminator or version strategy, implement the | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/DiscriminatorStrategy.html"> | |
<classname>org.apache.openjpa.jdbc.meta.DiscriminatorStrategy</classname> | |
</ulink> or | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/VersionStrategy.html"> | |
<classname>org.apache.openjpa.jdbc.meta.VersionStrategy</classname></ulink> | |
interface, respectively. You might extend one of the existing abstract or | |
concrete strategies in the <literal>org.apache.openjpa.jdbc.meta.strats | |
</literal> package. | |
</para> | |
<para> | |
OpenJPA includes the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/DiscriminatorStrategy.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.DiscriminatorStrategy</classname> | |
</ulink> and | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/VersionStrategy.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.VersionStrategy</classname> | |
</ulink> class annotations for declaring a custom discriminator or version | |
strategy in JPA mapping metadata. Set the string value of these annotations to | |
the full class name of your implementation, or to the class name or alias of an | |
existing OpenJPA implementation. | |
</para> | |
<para> | |
As with custom class mappings, you can configure your strategy class' bean | |
properties using OpenJPA's plugin syntax, detailed in | |
<xref linkend="ref_guide_conf_plugins"/>. | |
</para> | |
</section> | |
<section id="ref_guide_mapping_custom_field"> | |
<title> | |
Custom Field Mapping | |
</title> | |
<indexterm zone="ref_guide_mapping_custom_field"> | |
<primary> | |
custom mapping | |
</primary> | |
<secondary> | |
field mapping | |
</secondary> | |
</indexterm> | |
<para> | |
While custom class, discriminator, and version mapping can be useful, custom | |
field mappings are far more common. OpenJPA offers two types of custom field | |
mappings: value handlers, and full custom field strategies. The following | |
sections examine each. | |
</para> | |
<section id="ref_guide_mapping_custom_vhandler"> | |
<title> | |
Value Handlers | |
</title> | |
<indexterm zone="ref_guide_mapping_custom_fieldstrat"> | |
<primary> | |
custom mapping | |
</primary> | |
<secondary> | |
field mapping | |
</secondary> | |
<tertiary> | |
value handler | |
</tertiary> | |
</indexterm> | |
<para> | |
Value handlers make it trivial to map any type that you can break down into one | |
or more simple values. All value handlers implement the <classname> | |
org.apache.openjpa.jdbc.meta.ValueHandler</classname> interface; see its | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/ValueHandler.html"> Javadoc | |
</ulink> for details. Also, examine the built-in handlers in the <filename> | |
src/openjpa/jdbc/meta/strats</filename> directory of your OpenJPA source | |
distribution. Use these functional implementations as examples when you | |
create your own value handlers. | |
</para> | |
</section> | |
<section id="ref_guide_mapping_custom_fieldstrat"> | |
<title> | |
Field Strategies | |
</title> | |
<indexterm zone="ref_guide_mapping_custom_fieldstrat"> | |
<primary> | |
custom mapping | |
</primary> | |
<secondary> | |
field mapping | |
</secondary> | |
<tertiary> | |
field strategy | |
</tertiary> | |
</indexterm> | |
<para> | |
OpenJPA interacts with persistent fields through the | |
<ulink url="../javadoc/org/apache/openjpa/jdbc/meta/FieldStrategy"><classname> | |
org.apache.openjpa.jdbc.meta.FieldStrategy</classname></ulink> interface. You | |
can implement this interface yourself to create a custom field strategy, or | |
extend one of the existing abstract or concrete strategies in the <literal> | |
org.apache.openjpa.jdbc.meta.strats</literal> package. Creating a custom field | |
strategy is more difficult than writing a custom value handler, but gives you | |
more freedom in how you interact with the database. | |
</para> | |
</section> | |
<section id="ref_guide_mapping_custom_field_conf"> | |
<title> | |
Configuration | |
</title> | |
<indexterm zone="ref_guide_mapping_custom_field_conf"> | |
<primary> | |
custom mapping | |
</primary> | |
<secondary> | |
field mapping | |
</secondary> | |
<tertiary> | |
configuration | |
</tertiary> | |
</indexterm> | |
<para> | |
OpenJPA gives you two ways to configure your custom field mappings. The | |
<literal>FieldStrategies</literal> property of the built-in <classname> | |
MappingDefaults</classname> implementations allows you to globally associate | |
field types with their corresponding custom value handler or strategy. OpenJPA | |
will automatically use your custom strategies when it encounters a field of the | |
associated type. OpenJPA will use your custom value handlers whenever it | |
encounters a field of the associated type. | |
<xref linkend="ref_guide_mapping_defaults"/> described mapping | |
defaults in detail. | |
</para> | |
<para> | |
Your other option is to explicitly install a custom value handler or strategy on | |
a particular field. To do so, specify the full name of your implementation class | |
in the proper mapping metadata extension. OpenJPA includes the | |
<ulink url="../javadoc/org/apache/openjpa/persistence/jdbc/Strategy.html"> | |
<classname>org.apache.openjpa.persistence.jdbc.Strategy</classname></ulink> | |
annotation. You can configure the named strategy or handler's bean | |
properties in these extensions using OpenJPA's plugin format (see | |
<xref linkend="ref_guide_conf_plugins"/>). | |
</para> | |
</section> | |
</section> | |
</section> | |
<section id="ref_guide_orphan"> | |
<title> | |
Orphaned Keys | |
</title> | |
<para> | |
Unless you apply database foreign key constraints extensively, it is possible to | |
end up with orphaned keys in your database. For example, suppose <classname> | |
Magazine</classname><literal>m</literal> has a reference to <classname>Article | |
</classname><literal>a</literal>. If you delete <literal>a</literal> without | |
nulling <literal>m</literal>'s reference, <literal>m</literal>'s database | |
record will wind up with an orphaned key to the non-existent <literal>a | |
</literal> record. | |
</para> | |
<note> | |
<para> | |
One way of avoiding orphaned keys is to use <emphasis>dependent</emphasis> | |
fields. | |
</para> | |
</note> | |
<para> | |
OpenJPA's <link linkend="openjpa.OrphanedKeyAction"><literal> | |
openjpa.OrphanedKeyAction</literal></link> configuration property controls what | |
action to take when OpenJPA encounters an orphaned key. You can set this plugin | |
string (see <xref linkend="ref_guide_conf_plugins"/>) to a custom | |
implementation of the | |
<ulink url="../javadoc/org/apache/openjpa/event/OrphanedKeyAction.html"> | |
<classname> org.apache.openjpa.event.OrphanedKeyAction</classname></ulink> | |
interface, or use one of the built-in options: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>log</literal>: This is the default setting. This option logs a message | |
for each orphaned key. It is an alias for the | |
<ulink url="../javadoc/org/apache/openjpa/event/LogOrphanedKeyAction.html"> | |
<classname>org.apache.openjpa.event.LogOrphanedKeyAction</classname></ulink> | |
class, which has the following additional properties: | |
</para> | |
<itemizedlist> | |
<listitem> | |
<para> | |
<literal>Channel</literal>: The channel to log to. Defaults to <literal> | |
openjpa.Runtime</literal>. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>Level</literal>: The level to log at. Defaults to <literal>WARN | |
</literal>. | |
</para> | |
</listitem> | |
</itemizedlist> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>exception</literal>: Throw an <classname> | |
EntityNotFoundException</classname> when OpenJPA discovers an | |
orphaned key. This is an alias for the | |
<ulink url="../javadoc/org/apache/openjpa/event/ExceptionOrphanedKeyAction.html"> | |
<classname>org.apache.openjpa.event.ExceptionOrphanedKeyAction</classname> | |
</ulink> class. | |
</para> | |
</listitem> | |
<listitem> | |
<para> | |
<literal>none</literal>: Ignore orphaned keys. This is an alias for the | |
<ulink url="../javadoc/org/apache/openjpa/event/NoneOrphanedKeyAction.html"> | |
<classname>org.apache.openjpa.event.NoneOrphanedKeyAction</classname></ulink> | |
class. | |
</para> | |
</listitem> | |
</itemizedlist> | |
<example id="ref_guide_orphan_logex"> | |
<title> | |
Custom Logging Orphaned Keys | |
</title> | |
<programlisting> | |
<property name="openjpa.OrphanedKeyAction" value="log(Channel=Orphans, Level=DEBUG)"/> | |
</programlisting> | |
</example> | |
</section> | |
</chapter> |