blob: 6e27312bccf5481bb2ab49477d22e0f4b7f471cf [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>6.&nbsp; Non-Standard Joins</title><link rel="stylesheet" href="css/docbook.css" type="text/css"><base href="display"><meta name="generator" content="DocBook XSL Stylesheets V1.72.0"><link rel="start" href="manual.html" title="Apache OpenJPA 2.1 User's Guide"><link rel="up" href="ref_guide_mapping.html" title="Chapter&nbsp;7.&nbsp; Mapping"><link rel="prev" href="ref_guide_mapping_factory.html" title="5.&nbsp; Mapping Factory"><link rel="next" href="ref_guide_mapping_jpa.html" title="7.&nbsp; Additional JPA Mappings"></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">6.&nbsp;
Non-Standard Joins
</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ref_guide_mapping_factory.html">Prev</a>&nbsp;</td><th width="60%" align="center">Chapter&nbsp;7.&nbsp;
Mapping
</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="ref_guide_mapping_jpa.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_notes_nonstdjoins"></a>6.&nbsp;
Non-Standard Joins
</h2></div></div></div><a class="indexterm" name="d0e29519"></a><p>
The JPA Overview's <a href="jpa_overview_mapping.html" title="Chapter&nbsp;13.&nbsp; Mapping Metadata">Chapter&nbsp;13, <i xmlns:xlink="http://www.w3.org/1999/xlink">
Mapping Metadata
</i></a> 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.
</p><p>
<a class="indexterm" name="d0e29530"></a>
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.
</p><p>
<a class="indexterm" name="d0e29538"></a>
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
<a xmlns:xlink="http://www.w3.org/1999/xlink" href="../javadoc/org/apache/openjpa/jdbc/meta/Joinable.html" target="_top"><code class="classname">
org.apache.openjpa.jdbc.meta.Joinable</code></a> 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 <a href="ref_guide_mapping_custom.html" title="10.&nbsp; Custom Mappings">Section&nbsp;10, &#8220;
Custom Mappings
&#8221;</a> for an
examination of custom mappings.
</p><p>
<a class="indexterm" name="d0e29552"></a>
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 <span class="emphasis"><em>constant joins</em></span>.
</p><p>
To form a constant join in JPA mapping, first set the <code class="literal">JoinColumn
</code>'s <code class="literal">name</code> 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 <code class="literal">&lt;table name&gt;.&lt;column name&gt;
</code>. Next, set the <code class="literal">referencedColumnName</code> attribute to
the constant value. If the constant value is a string, place it in single quotes
to differentiate it from a column name.
</p><div class="mediaobject"><table border="0" summary="manufactured viewport for HTML img" cellspacing="0" cellpadding="0" width="285"><tr><td><img src="img/joins-constant.png"></td></tr></table></div><p>
Consider the tables above. First, we want to join row <code class="literal">T1.R1</code>
to row <code class="literal">T2.R1</code>. If we just join column <code class="literal">T1.FK</code>
to <code class="literal">T2.PK1</code>, we will wind up matching both <code class="literal">T2.R1
</code> and <code class="literal"> T2.R2</code>. So in addition to joining <code class="literal">
T1.FK</code> to <code class="literal">T2.PK1</code>, we also have to specify that
<code class="literal">T2.PK2</code> has the value <code class="literal">a</code>. Here is how we'd
accomplish this in mapping metadata.
</p><pre class="programlisting">
@Entity
@Table(name="T1")
public class ... {
@ManyToOne
@JoinColumns({
@JoinColumn(name="FK" referencedColumnName="PK1"),
@JoinColumn(name="T2.PK2" referencedColumnName="'a'")
});
private ...;
}
</pre><p>
Notice that we had to fully qualify the name of column <code class="literal">PK2</code>
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
<code class="literal">T1.R2</code> to <code class="literal">T2.R4</code> is:
</p><pre class="programlisting">
@Entity
@Table(name="T1")
public class ... {
@ManyToOne
@JoinColumns({
@JoinColumn(name="FK" referencedColumnName="PK2"),
@JoinColumn(name="T2.PK1" referencedColumnName="2")
});
private ...;
}
</pre><p>
Finally, from the inverse direction, these joins would look like this:
</p><pre class="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 ...;
}
</pre></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ref_guide_mapping_factory.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="ref_guide_mapping.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="ref_guide_mapping_jpa.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.&nbsp;
Mapping Factory
&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="manual.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;7.&nbsp;
Additional JPA Mappings
</td></tr></table></div></body></html>