| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>7. Additional JPA Mappings</title><link rel="stylesheet" href="css/docbook.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.72.0"><link rel="start" href="manual.html" title="Apache OpenJPA User's Guide"><link rel="up" href="ref_guide_mapping.html" title="Chapter 7. Mapping"><link rel="prev" href="ref_guide_mapping_notes_nonstdjoins.html" title="6. Non-Standard Joins"><link rel="next" href="ref_guide_mapping_limits.html" title="8. Mapping Limitations"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">7. |
| Additional JPA Mappings |
| </th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ref_guide_mapping_notes_nonstdjoins.html">Prev</a> </td><th width="60%" align="center">Chapter 7. |
| Mapping |
| </th><td width="20%" align="right"> <a accesskey="n" href="ref_guide_mapping_limits.html">Next</a></td></tr></table><hr></div><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="ref_guide_mapping_jpa"></a>7. |
| Additional JPA Mappings |
| </h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_datastoreid">7.1. |
| Datastore Identity Mapping |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_version">7.2. |
| Surrogate Version Mapping |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_columns">7.3. |
| Multi-Column Mappings |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_fieldjoin">7.4. |
| Join Column Attribute Targets |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_embed">7.5. |
| Embedded Mapping |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_coll">7.6. |
| Collections |
| </a></span></dt><dd><dl><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_coll_table">7.6.1. |
| Container Table |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_coll_joincols">7.6.2. |
| Element Join Columns |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_coll_order">7.6.3. |
| Order Column |
| </a></span></dt></dl></dd><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_onemany">7.7. |
| One-Sided One-Many Mapping |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_map">7.8. |
| Maps |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_constraints">7.9. |
| Indexes and Constraints |
| </a></span></dt><dd><dl><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_index">7.9.1. |
| Indexes |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_fk">7.9.2. |
| Foreign Keys |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_unique">7.9.3. |
| Unique Constraints |
| </a></span></dt></dl></dd><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_xmlmapping">7.10. |
| XML Column Mapping |
| </a></span></dt></dl></div><a class="indexterm" name="d0e25063"></a><p> |
| OpenJPA supports many persistence strategies beyond those of the JPA |
| specification. <a href="ref_guide_meta_jpa.html" title="2. Additional JPA Metadata">Section 2, “ |
| Additional JPA Metadata |
| ”</a> covered the logical |
| metadata for OpenJPA's additional persistence strategies. We now demonstrate how |
| to map entities using these strategies to the database. |
| </p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="ref_guide_mapping_jpa_datastoreid"></a>7.1. |
| Datastore Identity Mapping |
| </h3></div></div></div><a class="indexterm" name="d0e25075"></a><a class="indexterm" name="d0e25080"></a><a class="indexterm" name="d0e25087"></a><a class="indexterm" name="d0e25092"></a><p> |
| <a href="ref_guide_pc_oid.html" title="3. Object Identity">Section 3, “ |
| Object Identity |
| ”</a> describes how to use datastore identity |
| in JPA. OpenJPA requires a single numeric primary key column to hold datastore |
| identity values. The |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/DataStoreIdColumn.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.DataStoreIdColumn</code> |
| </a> annotation customizes the datastore identity column. This annotation |
| has the following properties: |
| </p><div class="itemizedlist"><ul type="disc"><li><p> |
| <code class="literal">String name</code>: Defaults to <code class="literal">ID</code>. |
| </p></li><li><p> |
| <code class="literal">int precision</code> |
| </p></li><li><p> |
| <code class="literal">String columnDefinition</code> |
| </p></li><li><p> |
| <code class="literal">boolean insertable</code> |
| </p></li><li><p> |
| <code class="literal">boolean updatable</code> |
| </p></li></ul></div><p> |
| All properties correspond exactly to the same-named properties on the standard |
| <code class="classname">Column</code> annotation, described in |
| <a href="jpa_overview_mapping_column.html" title="3. Column">Section 3, “ |
| Column |
| ”</a>. |
| </p><div class="example"><a name="ref_guide_mapping_jpa_datastoreidex"></a><p class="title"><b>Example 7.14. |
| Datastore Identity Mapping |
| </b></p><div class="example-contents"><pre class="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; |
| |
| ... |
| } |
| </pre></div></div><br class="example-break"></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="ref_guide_mapping_jpa_version"></a>7.2. |
| Surrogate Version Mapping |
| </h3></div></div></div><a class="indexterm" name="d0e25154"></a><a class="indexterm" name="d0e25159"></a><a class="indexterm" name="d0e25166"></a><p> |
| 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 |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/VersionColumn.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.VersionColumn</code></a> |
| annotation. You can also use the |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/VersionColumns.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.VersionColumns</code> |
| </a> annotation to declare an array of <code class="classname">VersionColumn</code> |
| values. Each <code class="classname">VersionColumn</code> has the following properties: |
| </p><div class="itemizedlist"><ul type="disc"><li><p> |
| <code class="literal">String name</code>: Defaults to <code class="literal">VERSN</code>. |
| </p></li><li><p> |
| <code class="literal">int length</code> |
| </p></li><li><p> |
| <code class="literal">int precision</code> |
| </p></li><li><p> |
| <code class="literal">int scale</code> |
| </p></li><li><p> |
| <code class="literal">String columnDefinition</code> |
| </p></li><li><p> |
| <code class="literal">boolean nullable</code> |
| </p></li><li><p> |
| <code class="literal">boolean insertable</code> |
| </p></li><li><p> |
| <code class="literal">boolean updatable</code> |
| </p></li></ul></div><p> |
| All properties correspond exactly to the same-named properties on the standard |
| <code class="classname">Column</code> annotation, described in |
| <a href="jpa_overview_mapping_column.html" title="3. Column">Section 3, “ |
| Column |
| ”</a>. |
| </p><p> |
| By default, OpenJPA assumes that surrogate versioning uses a version number |
| strategy. You can choose a different strategy with the <code class="classname"> |
| VersionStrategy</code> annotation described in |
| <a href="ref_guide_mapping_ext.html#version-strategy" title="9.1.4. Version Strategy">Section 9.1.4, “ |
| Version Strategy |
| ”</a>. |
| </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="ref_guide_mapping_jpa_columns"></a>7.3. |
| Multi-Column Mappings |
| </h3></div></div></div><a class="indexterm" name="d0e25259"></a><a class="indexterm" name="d0e25264"></a><a class="indexterm" name="d0e25269"></a><p> |
| OpenJPA makes it easy to create multi-column |
| <a href="ref_guide_mapping_custom.html#ref_guide_mapping_custom_field" title="10.3. Custom Field Mapping">custom mappings</a>. The JPA |
| specification includes a <code class="classname">Column</code> annotation, but is |
| missing a way to declare multiple columns for a single field. OpenJPA remedies |
| this with the |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/Columns.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.Columns</code></a> |
| annotation, which contains an array of <code class="classname">Column</code> values. |
| </p><p> |
| Remember to annotate custom field types with <code class="classname">Persistent</code>, |
| as described in <a href="ref_guide_meta_jpa.html#ref_guide_meta_jpa_persistent" title="2.3. Persistent Field Values">Section 2.3, “ |
| Persistent Field Values |
| ”</a>. |
| </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="ref_guide_mapping_jpa_fieldjoin"></a>7.4. |
| Join Column Attribute Targets |
| </h3></div></div></div><p> |
| <a href="jpa_overview_mapping_field.html#jpa_overview_mapping_rel" title="8.4. Direct Relations">Section 8.4, “ |
| Direct Relations |
| ”</a> in the JPA Overview introduced |
| you to the <code class="classname">JoinColumn</code> annotation. A <code class="classname"> |
| JoinColumn</code>'s <code class="literal"> referencedColumnName</code> 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 |
| <code class="literal">referencedColumnName</code> that works for all subclasses. |
| </p><p> |
| OpenJPA rectifies this by allowing you to declare which <span class="emphasis"><em>attribute |
| </em></span> 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 |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/XJoinColumn.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.XJoinColumn</code></a> |
| annotation has all the same properties as the standard <code class="classname">JoinColumn |
| </code> annotation, but adds an additional <code class="literal"> |
| referencedAttributeName</code> property for this purpose. Simply use a |
| <code class="classname">XJoinColumn</code> in place of a <code class="classname">JoinColumn |
| </code> whenever you need to access this added functionality. |
| </p><p> |
| For compound keys, use the |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/XJoinColumns.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.XJoinColumns</code></a> |
| annotation. The value of this annotation is an array of individual <code class="classname"> |
| XJoinColumn</code>s. |
| </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="ref_guide_mapping_jpa_embed"></a>7.5. |
| Embedded Mapping |
| </h3></div></div></div><p> |
| JPA uses the <code class="classname">AttributeOverride</code> annotation to override the |
| default mappings of an embeddable class. The JPA Overview details this process |
| in <a href="jpa_overview_mapping_field.html#jpa_overview_mapping_embed" title="8.3. Embedded Mapping">Section 8.3, “ |
| Embedded Mapping |
| ”</a>. <code class="classname"> |
| AttributeOverride</code>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. |
| </p><p> |
| OpenJPA overcomes these shortcomings with the |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/EmbeddedMapping.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.EmbeddedMapping</code> |
| </a> annotation. This annotation has the following properties: |
| </p><div class="itemizedlist"><ul type="disc"><li><p> |
| <code class="literal">String nullIndicatorColumnName</code>: If the named column's value |
| is <code class="literal">NULL</code>, then the embedded object is assumed to be null. If |
| the named column has a non- <code class="literal">NULL</code> 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. |
| </p><p> |
| 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 <code class="literal">true</code> to simply indicate that you |
| want a synthetic null-indicator column, without having to come up with a name |
| for it. A value of <code class="literal">false</code> signals that you explicitly do not |
| want a null-indicator column created for this mapping (in case you have |
| configured your <a href="ref_guide_mapping_defaults.html" title="4. Mapping Defaults">mapping defaults |
| </a> to create one by default). |
| </p></li><li><p> |
| <code class="literal">String nullIndicatorFieldName</code>: 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. |
| </p></li><li><p> |
| <code class="literal">MappingOverride[] overrides</code>: This array allows you to |
| override any mapping of the embedded object. |
| </p></li></ul></div><p> |
| The <code class="classname">EmbeddedMapping</code>'s <code class="literal">overrides</code> array |
| serves the same purpose as standard JPA's <code class="classname">AttributeOverride |
| </code>s and <code class="classname">AssociationOverride</code> s. In fact, you can |
| also use the <code class="classname">MappingOverride</code> annotation on an entity |
| class to override a complex mapping of its mapped superclass, just as you can |
| with <code class="classname"> AttributeOverride</code> and <code class="classname"> |
| AssociationOverride</code> s. The <code class="classname">MappingOverrides</code> |
| annotation, whose value is an array of <code class="classname">MappingOverride</code> s, |
| allows you to overide multiple mapped superclass mappings. |
| </p><p> |
| Each |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/MappingOverride.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.MappingOverride</code> |
| </a> annotation has the following properties: |
| </p><div class="itemizedlist"><ul type="disc"><li><p> |
| <code class="literal">String name</code>: The name of the field that is being overridden. |
| </p></li><li><p> |
| <code class="literal">Column[] columns</code>: Columns for the new field mapping. |
| </p></li><li><p> |
| <code class="literal">XJoinColumn[] joinColumns</code>: Join columns for the new field |
| mapping, if it is a relation field. |
| </p></li><li><p> |
| <code class="literal">ContainerTable containerTable</code>: Table for the new collection |
| or map field mapping. We cover collection mappings in |
| <a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_coll" title="7.6. Collections">Section 7.6, “ |
| Collections |
| ”</a>, and map mappings in |
| <a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_map" title="7.8. Maps">Section 7.8, “ |
| Maps |
| ”</a>. |
| </p></li><li><p> |
| <code class="literal">ElementJoinColumn[] elementJoinColumns</code>: Element join columns |
| for the new collection or map field mapping. You will see how to use element |
| join columns in <a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_coll_joincols" title="7.6.2. Element Join Columns">Section 7.6.2, “ |
| Element Join Columns |
| ”</a>. |
| </p></li></ul></div><p> |
| The following example defines an embeddable <code class="classname"> PathCoordinate |
| </code> class with a custom mapping of a <code class="classname">java.awt.Point |
| </code> field to two columns. It then defines an entity which embeds a |
| <code class="classname"> PointCoordinate</code> and overrides the default mapping for |
| the point field. The entity also declares that if the <code class="classname">PathCoordinate |
| </code>'s <code class="literal">siteName</code> field column is null, it means that |
| no <code class="classname">PathCoordinate</code> is stored in the embedded record; the |
| owning field will load as null. |
| </p><div class="example"><a name="ref_guide_mapping_jpa_embedex"></a><p class="title"><b>Example 7.15. |
| Overriding Complex Mappings |
| </b></p><div class="example-contents"><pre class="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; |
| |
| ... |
| } |
| </pre></div></div><br class="example-break"></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="ref_guide_mapping_jpa_coll"></a>7.6. |
| Collections |
| </h3></div></div></div><div class="toc"><dl><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_coll_table">7.6.1. |
| Container Table |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_coll_joincols">7.6.2. |
| Element Join Columns |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_coll_order">7.6.3. |
| Order Column |
| </a></span></dt></dl></div><a class="indexterm" name="d0e25507"></a><p> |
| In <a href="ref_guide_meta_jpa.html#ref_guide_meta_jpa_persistent_coll" title="2.4. Persistent Collection Fields">Section 2.4, “Persistent Collection Fields”</a>, we explored the |
| <code class="classname">PersistentCollection</code> annotation for persistent collection |
| fields that aren't a standard <code class="literal">OneToMany</code> or <code class="literal"> |
| ManyToMany</code> relation. To map these non-standard collections, combine |
| OpenJPA's <code class="classname">ContainerTable</code> annotation with |
| <code class="classname">ElementJoinColumn</code>s. |
| We explore the annotations below. |
| </p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="ref_guide_mapping_jpa_coll_table"></a>7.6.1. |
| Container Table |
| </h4></div></div></div><a class="indexterm" name="d0e25534"></a><p> |
| The |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/ContainerTable.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.ContainerTable</code> |
| </a> annotation describes a database table that holds collection (or map) |
| elements. This annotation has the following properties: |
| </p><div class="itemizedlist"><ul type="disc"><li><p> |
| <code class="literal">String name</code> |
| </p></li><li><p> |
| <code class="literal">String catalog</code> |
| </p></li><li><p> |
| <code class="literal">String schema</code> |
| </p></li><li><p> |
| <code class="literal">XJoinColumn[] joinColumns</code> |
| </p></li><li><p> |
| <code class="literal">ForeignKey joinForeignKey</code> |
| </p></li><li><p> |
| <code class="literal">Index joinIndex</code> |
| </p></li></ul></div><p> |
| The <code class="literal">name</code>, <code class="literal">catalog</code>, <code class="literal">schema |
| </code>, and <code class="literal">joinColumns</code> 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 <code class="classname"> JoinTable</code> |
| annotation, described in <a href="jpa_overview_mapping_field.html#jpa_overview_mapping_assoccoll" title="8.5. Join Table">Section 8.5, “ |
| Join Table |
| ”</a> |
| . 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 <code class="literal">joinForeignKey</code> and <code class="literal"> joinIndex</code> |
| properties override default foreign key and index generation for the join |
| columns. We explore foreign keys and indexes later in this chapter. |
| </p><p> |
| 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. |
| </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="ref_guide_mapping_jpa_coll_joincols"></a>7.6.2. |
| Element Join Columns |
| </h4></div></div></div><a class="indexterm" name="d0e25614"></a><p> |
| 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 |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/ElementJoinColumn.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.ElementJoinColumn</code> |
| </a> annotation. To declare a compound join, enclose an array of <code class="classname"> |
| ElementJoinColumn</code>s in the |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/ElementJoinColumns.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.ElementJoinColumns</code> |
| </a> annotation. |
| </p><p> |
| An <code class="classname">ElementJoinColumn</code> always resides in a container table, |
| so it does not have the <code class="literal"> table</code> property of a standard |
| <code class="classname"> JoinColumn</code>. Like <code class="classname"> XJoinColumn</code>s |
| above, <code class="classname"> ElementJoinColumn</code>s can reference a linked |
| attribute rather than a static linked column. Otherwise, the <code class="classname"> |
| ElementJoinColumn</code> and standard <code class="classname">JoinColumn</code> |
| annotations are equivalent. See <a href="jpa_overview_mapping_field.html#jpa_overview_mapping_rel" title="8.4. Direct Relations">Section 8.4, “ |
| Direct Relations |
| ”</a> |
| in the JPA Overview for a review of the <code class="classname">JoinColumn</code> |
| annotation. |
| </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="ref_guide_mapping_jpa_coll_order"></a>7.6.3. |
| Order Column |
| </h4></div></div></div><a class="indexterm" name="d0e25667"></a><p> |
| 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 |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/OrderColumn" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.OrderColumn</code></a> |
| annotation has the following properties: |
| </p><div class="itemizedlist"><ul type="disc"><li><p> |
| <code class="literal">String name</code>: Defaults to <code class="literal">ORDR</code>. |
| </p></li><li><p> |
| <code class="literal">boolean enabled</code> |
| </p></li><li><p> |
| <code class="literal">int precision</code> |
| </p></li><li><p> |
| <code class="literal">String columnDefinition</code> |
| </p></li><li><p> |
| <code class="literal">boolean insertable</code> |
| </p></li><li><p> |
| <code class="literal">boolean updatable</code> |
| </p></li></ul></div><p> |
| Order columns are always in the container table. You can explicitly turn off |
| ordering (if you have enabled it by default via your |
| <a href="ref_guide_mapping_defaults.html" title="4. Mapping Defaults"> mapping defaults</a>) by setting |
| the <code class="literal">enabled</code> property to <code class="literal">false</code>. All other |
| properties correspond exactly to the same-named properties on the standard |
| <code class="classname">Column</code> annotation, described in |
| <a href="jpa_overview_mapping_column.html" title="3. Column">Section 3, “ |
| Column |
| ”</a>. |
| </p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="ref_guide_mapping_jpa_onemany"></a>7.7. |
| One-Sided One-Many Mapping |
| </h3></div></div></div><a class="indexterm" name="d0e25738"></a><p> |
| The previous section covered the use of <code class="classname">ElementJoinColumn</code> |
| annotations in conjunction with a <code class="classname">ContainerTable</code> for |
| mapping collections to dedicate tables. <code class="classname">ElementJoinColumn</code> |
| s, however, have one additional use: to create a one-sided one-many mapping. |
| Standard JPA supports <code class="classname">OneToMany</code> fields without a |
| <code class="literal">mappedBy</code> inverse, but only by mapping these fields to a |
| <code class="classname">JoinTable</code> (see |
| <a href="jpa_overview_mapping_field.html#jpa_overview_mapping_assoccoll" title="8.5. Join Table">Section 8.5, “ |
| Join Table |
| ”</a> 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. |
| </p><div class="mediaobject"><table border="0" summary="manufactured viewport for HTML img" cellspacing="0" cellpadding="0" width="261"><tr><td><img src="img/inv-key-coll.png"></td></tr></table></div><p> |
| Consider the model above. <code class="classname">Subscription</code> has a collection |
| of <code class="classname">LineItem</code> s, but <code class="classname">LineItem</code> has |
| no inverse relation to <code class="classname">Subscription</code>. To retrieve all of |
| the <code class="classname">LineItem</code> records for a <code class="classname">Subscription |
| </code>, we join the <code class="literal">SUB_ID</code> inverse foreign key column |
| in the <code class="literal">LINE_ITEM</code> table to the primary key column of the |
| <code class="literal">SUB</code> 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. |
| </p><div class="example"><a name="ref_guide_mapping_jpa_onemanyex"></a><p class="title"><b>Example 7.16. |
| One-Sided One-Many Mapping |
| </b></p><div class="example-contents"><pre class="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; |
| |
| ... |
| } |
| </pre></div></div><br class="example-break"></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="ref_guide_mapping_jpa_map"></a>7.8. |
| Maps |
| </h3></div></div></div><a class="indexterm" name="d0e25808"></a><p> |
| We detailed the <code class="literal">ContainerTable</code> annotation in |
| <a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_coll_table" title="7.6.1. Container Table">Section 7.6.1, “ |
| Container Table |
| ”</a>. Custom map mappings may |
| also use this annotation to represent a map table. |
| </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="ref_guide_mapping_jpa_constraints"></a>7.9. |
| Indexes and Constraints |
| </h3></div></div></div><div class="toc"><dl><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_index">7.9.1. |
| Indexes |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_fk">7.9.2. |
| Foreign Keys |
| </a></span></dt><dt><span class="section"><a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_unique">7.9.3. |
| Unique Constraints |
| </a></span></dt></dl></div><p> |
| 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. |
| </p><p> |
| OpenJPA assumes certain columns have indexes or constraints based on your |
| mapping defaults, as detailed in <a href="ref_guide_mapping_defaults.html" title="4. Mapping Defaults">Section 4, “ |
| Mapping Defaults |
| ”</a>. |
| 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. |
| </p><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="ref_guide_mapping_jpa_index"></a>7.9.1. |
| Indexes |
| </h4></div></div></div><a class="indexterm" name="d0e25832"></a><a class="indexterm" name="d0e25837"></a><p> |
| The <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/Index.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.Index</code></a> |
| annotation represents an index on the columns of a field. It is also used within |
| the <a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_coll_table" title="7.6.1. Container Table"><code class="classname">ContainerTable |
| </code></a> annotation to index join columns. |
| To index the columns of a collection element, use the |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/ElementIndex.html" target="_top"> |
| <code class="classname"> org.apache.openjpa.persistence.jdbc.ElementIndex</code></a> |
| annotation. These annotations have the following properties: |
| </p><div class="itemizedlist"><ul type="disc"><li><p> |
| <code class="literal">boolean enabled</code>: Set this property to <code class="literal">false |
| </code> to explicitly tell OpenJPA not to index these columns, when OpenJPA |
| would otherwise do so. |
| </p></li><li><p> |
| <code class="literal">String name</code>: The name of the index. OpenJPA will choose a |
| name if you do not provide one. |
| </p></li><li><p> |
| <code class="literal">boolean unique</code>: Whether to create a unique index. Defaults |
| to false. |
| </p></li></ul></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="ref_guide_mapping_jpa_fk"></a>7.9.2. |
| Foreign Keys |
| </h4></div></div></div><a class="indexterm" name="d0e25881"></a><a class="indexterm" name="d0e25886"></a><p> |
| The <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/ForeignKey.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.ForeignKey</code></a> |
| annotation represents a foreign key on the columns of a field. It is also used |
| within the <a href="ref_guide_mapping_jpa.html#ref_guide_mapping_jpa_coll_table" title="7.6.1. Container Table"><code class="classname"> |
| ContainerTable</code></a> annotation to set a database foreign key on |
| join columns. To set a constraint to the columns of a collection element, use |
| the |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/ElementForeignKey.html" target="_top"> |
| <code class="classname"> org.apache.openjpa.persistence.jdbc.ElementForeignKey</code> |
| </a> annotation. These annotations have the following properties: |
| </p><div class="itemizedlist"><ul type="disc"><li><p> |
| <code class="literal">boolean enabled</code>: Set this property to <code class="literal">false |
| </code> to explicitly tell OpenJPA not to set a foreign key on these columns, |
| when OpenJPA would otherwise do so. |
| </p></li><li><p> |
| <code class="literal">String name</code>: The name of the foreign key. OpenJPA will |
| choose a name if you do not provide one, or will create an anonymous key. |
| </p></li><li><p> |
| <code class="literal">boolean deferred</code>: Whether to create a deferred key if |
| supported by the database. |
| </p></li><li><p> |
| <code class="literal">ForeignKeyAction deleteAction</code>: Value from the |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/ForeignKeyAction.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.ForeignKeyAction</code> |
| </a> enum identifying the desired delete action. Defaults to <code class="literal"> |
| RESTRICT</code>. |
| </p></li><li><p> |
| <code class="literal">ForeignKeyAction updateAction</code>: Value from the |
| <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/ForeignKeyAction.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.ForeignKeyAction</code> |
| </a> enum identifying the desired update action. Defaults to <code class="literal"> |
| RESTRICT</code>. |
| </p></li></ul></div><p> |
| Keep in mind that OpenJPA uses foreign key information at runtime to avoid |
| constraint violations; it is important, therefore, that your |
| <a href="ref_guide_mapping_defaults.html" title="4. Mapping Defaults">mapping defaults</a> 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 |
| <a href="ref_guide_schema_info.html#ref_guide_schema_info_factory" title="11.2. Schema Factory">Section 11.2, “ |
| Schema Factory |
| ”</a>). |
| </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h4 class="title"><a name="ref_guide_mapping_jpa_unique"></a>7.9.3. |
| Unique Constraints |
| </h4></div></div></div><a class="indexterm" name="d0e25968"></a><a class="indexterm" name="d0e25973"></a><p> |
| The <a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/persistence/jdbc/Unique.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.jdbc.Unique</code></a> |
| annotation represents a unqiue constraint on the columns of a field. It is more |
| convenient than using the <code class="literal">uniqueConstraints</code> property of |
| standard JPA <code class="classname">Table</code> and <code class="classname">SecondaryTable |
| </code> annotations, because you can apply it directly to the constrained |
| field. The <code class="classname">Unique</code> annotation has the following |
| properties: |
| </p><div class="itemizedlist"><ul type="disc"><li><p> |
| <code class="literal">boolean enabled</code>: Set this property to <code class="literal">false |
| </code> to explicitly tell OpenJPA not to constrain these columns, when |
| OpenJPA would otherwise do so. |
| </p></li><li><p> |
| <code class="literal">String name</code>: The name of the constraint. OpenJPA will choose |
| a name if you do not provide one, or will create an anonymous constraint. |
| </p></li><li><p> |
| <code class="literal">boolean deferred</code>: Whether to create a deferred constraint if |
| supported by the database. |
| </p></li></ul></div></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="ref_guide_xmlmapping"></a>7.10. |
| XML Column Mapping |
| </h3></div></div></div><a class="indexterm" name="d0e26020"></a><a class="indexterm" name="d0e26025"></a><p> |
| 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. |
| </p><p> |
| Annotate the entity property using the XMLValueHandler strategy: |
| </p><pre class="programlisting"> |
| @Persistent |
| @Strategy("org.apache.openjpa.jdbc.meta.strats.XMLValueHandler") |
| </pre><p> |
| The default fetch type is EAGER but can be changed to LAZY by using: |
| </p><pre class="programlisting"> |
| @Persistence(fetch=FetchType.LAZY) |
| </pre><p> |
| 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 <code class="classname">@XmlRootElement</code> |
| appears in the root class. In some case this annotation needs to be added manually if it is missing. |
| </p><p> |
| The jaxb jar files must be on the application classpath (jaxb-api.jar, |
| jaxb-impl.jar, jsr173_1.0_api.jar or equivalent). |
| </p><p> |
| EJB Query path expressions can navigate into the mapped class and its |
| subfields to any level. |
| </p><p> |
| The path expression is rewritten into an equivalent XPATH expression using SQL |
| XML functions. |
| </p><p> |
| 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 |
| (= <> < > >= <=). |
| </p><p> |
| Path expressions over XML mapped fields can not be: |
| </p><div class="itemizedlist"><ul type="disc"><li><p> |
| an input to a EJB query scalar function |
| </p></li><li><p> |
| an operand of BETWEEN, IS NULL, LIKE or IN predicate |
| </p></li><li><p> |
| used to project out subfields in the SELECT clause |
| </p></li><li><p> |
| used in the FROM , GROUP BY, HAVING, ORDER BY clauses |
| </p></li></ul></div><p> |
| 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. |
| </p><p> |
| The datatype generated by JAXB must be a valid EJB query type |
| to use the property in an EJB query predicate. |
| </p><p> |
| Shown below is a sample XML schema <a href="ref_guide_mapping_jpa.html#ref_guide_xmlmapping_myaddress" title="Example 7.17. myaddress.xsd">myaddress.xsd</a>, |
| in which the JPA entity Order has <code class="classname"><shipAddress></code> persistent field that maps to an XML column. |
| </p><div class="example"><a name="ref_guide_xmlmapping_myaddress"></a><p class="title"><b>Example 7.17. |
| myaddress.xsd |
| </b></p><div class="example-contents"><pre class="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> |
| </pre></div></div><br class="example-break"><p> |
| Java classes <a href="ref_guide_mapping_jpa.html#ref_guide_xmlmapping_address" title="Example 7.18. Address.Java">Address</a>, |
| <a href="ref_guide_mapping_jpa.html#ref_guide_xmlmapping_usaaddress" title="Example 7.19. USAAddress.java">USAAddress</a> and |
| <a href="ref_guide_mapping_jpa.html#ref_guide_xmlmapping_canaddress" title="Example 7.20. CANAddress.java">CANAddress</a> |
| are produced using jaxb XJC generator from myaddress schema. |
| </p><div class="example"><a name="ref_guide_xmlmapping_address"></a><p class="title"><b>Example 7.18. |
| Address.Java |
| </b></p><div class="example-contents"><pre class="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. |
| * |
| */ |
| ... |
| } |
| </pre></div></div><br class="example-break"><div class="example"><a name="ref_guide_xmlmapping_usaaddress"></a><p class="title"><b>Example 7.19. |
| USAAddress.java |
| </b></p><div class="example-contents"><pre class="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. |
| * |
| */ |
| ... |
| } |
| </pre></div></div><br class="example-break"><div class="example"><a name="ref_guide_xmlmapping_canaddress"></a><p class="title"><b>Example 7.20. |
| CANAddress.java |
| </b></p><div class="example-contents"><pre class="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. |
| * |
| */ |
| ... |
| } |
| </pre></div></div><br class="example-break"><div class="example"><a name="ref_guide_xmlmapping_annorder"></a><p class="title"><b>Example 7.21. |
| Showing annotated Order entity with XML mapping strategy |
| </b></p><div class="example-contents"><pre class="programlisting"> |
| @Entity |
| public class Order { |
| @Id private into id; |
| @Persistent |
| @Strategy ("org.apache.openjpa.jdbc.meta.strats.XMLValueHandler") |
| private Address shipAddress; |
| ... |
| } |
| </pre></div></div><br class="example-break"><div class="example"><a name="ref_guide_xmlmapping_createorder"></a><p class="title"><b>Example 7.22. |
| Showing creation of Order Entity having shipAddress mapped to XML column |
| </b></p><div class="example-contents"><pre class="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); |
| ... |
| </pre></div></div><br class="example-break"><div class="example"><a name="ref_guide_xmlmapping_ejbquery"></a><p class="title"><b>Example 7.23. |
| Sample EJB Queries for XML Column mapping |
| </b></p><div class="example-contents"><pre class="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) |
| </pre></div></div><br class="example-break"></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ref_guide_mapping_notes_nonstdjoins.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ref_guide_mapping.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ref_guide_mapping_limits.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">6. |
| Non-Standard Joins |
| </td><td width="20%" align="center"><a accesskey="h" href="manual.html">Home</a></td><td width="40%" align="right" valign="top"> 8. |
| Mapping Limitations |
| </td></tr></table></div></body></html> |