blob: cb7a378a59411128de0d8d69896a70915a74b986 [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title>Binding JPA Entities to XML | EclipseLink 2.7 Understanding EclipseLink</title>
<meta name="generator" content="Oracle DARB XHTML Converter (Mode = document) - Version 1.0.22 Build 1" />
<meta name="date" content="2014-06-10T10:35:15Z" />
<meta name="robots" content="noarchive" />
<meta name="doctitle" content="Binding JPA Entities to XML" />
<meta name="relnum" content="Release 2.7" />
<link rel="stylesheet" type="text/css" href="../../dcommon/style.css" media="screen" />
<link rel="copyright" href="../../dcommon/html/cpyr.htm" title="Copyright" type="text/html" />
<link rel="start" href="../../index.htm" title="Home" type="text/html" />
<link rel="contents" href="toc.htm" title="Contents" type="text/html" />
<link rel="prev" href="jpatoxml001.htm" title="Previous" type="text/html" />
<link rel="next" href="jpatoxml003.htm" title="Next" type="text/html" />
<!-- START: Disqus --><script type="text/javascript"> var disqus_developer = 0; </script><!-- END: Disqus --><!-- START: Sharethis --><script type="text/javascript">var switchTo5x=true;</script><script type="text/javascript" src="http://w.sharethis.com/button/buttons.js"></script><script type="text/javascript" src="http://s.sharethis.com/loader.js"></script> <!-- END: Sharethis --></head>
<body bgcolor="#FFFFFF"><iframe id="docheader" frameborder="0" framemargin="0" scrolling="no" src="../../dcommon/header.html"></iframe><script src="http://www.google.com/jsapi" type="text/javascript"></script><script type="text/javascript"> google.load('search', '1', {language : 'en'}); google.setOnLoadCallback(function() { var customSearchOptions = {}; var googleAnalyticsOptions = {}; googleAnalyticsOptions['queryParameter'] = 'q'; googleAnalyticsOptions['categoryParameter'] = ''; customSearchOptions['googleAnalyticsOptions'] = googleAnalyticsOptions; var customSearchControl = new google.search.CustomSearchControl( '016171230611334810008:enkkfjmsqju', customSearchOptions); customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET); var options = new google.search.DrawOptions(); options.setSearchFormRoot('cse-search-form'); customSearchControl.draw('cse', options); }, true);</script><link rel="stylesheet" href="http://www.google.com/cse/style/look/default.css" type="text/css" /><div id="cse" style="width:100%;"></div>
<div class="header"><a id="top" name="top"></a>
<table class="simple oac_no_warn" summary="" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td align="left" valign="top"><font face="helvetica, arial, sans-serif"><b>EclipseLink Solutions Guide for EclipseLink</b><br />
Release 2.7</div></td>
<td valign="bottom" align="right" width="144">
<table class="simple oac_no_warn" summary="" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td>&nbsp;</td>
<td align="center" valign="top"><a href="toc.htm"><img src="../../dcommon/images/contents.png" alt="Go To Table Of Contents" border="0" height="16" width="16" /><br />
</td><td>&nbsp;</td><td align="center"><a href="../../" target="_top" class="external text" title="Search" rel="nofollow"><img src="../../dcommon/images/search.png" alt="Search" style="border:0;" /><br /><span class="mini"></span></a></td><td>&nbsp;</td><td align="center"><a href="../eclipselink_otlcg.pdf" title="PDF" target="_blank"><img src="../../dcommon/images/pdf_icon.png" style="padding-right:5px;border:0" alt="PDF"></a></td>
</tr>
</table>
</td>
</tr>
</table>
<hr />
<table class="navigation simple oac_no_warn" summary="" cellspacing="0" cellpadding="0" width="100" align="center">
<tr>
<td align="center"><a href="jpatoxml001.htm"><img src="../../dcommon/images/larrow.png" alt="Previous" border="0" height="16" width="16" /></a></td>
<td align="center"><a href="jpatoxml003.htm"><img src="../../dcommon/images/rarrow.png" alt="Next" border="0" height="16" width="16" /></a></td>
<td>&nbsp;</td>
</tr>
</table>
</div>
<!-- class="header" -->
<div class="ind"><!-- End Header --><a id="BEIGDBHI" name="BEIGDBHI"></a><a id="TLADG293" name="TLADG293"></a>
<div class="sect1"><!-- infolevel="all" infotype="General" -->
<h1 class="sect1"><font face="arial, helvetica, sans-serif" color="#330099">Binding JPA Entities to XML</font></h1>
<p>The following examples demonstrate how to bind JPA entities to XML by using JAXB annotations. For more information about binding, see <a href="jpatoxml001.htm#BEIEHDIH">Understanding XML Binding</a> for more information about JAXB, see <a href="jpatoxml001.htm#BEIJHDEG">Understanding JAXB</a></p>
<ul>
<li>
<p><a href="#BEICADBF">Binding JPA Relationships to XML</a></p>
</li>
<li>
<p><a href="#BEIIHFJG">Binding Compound Primary Keys to XML</a></p>
</li>
<li>
<p><a href="#BEIECBGA">Binding Embedded ID Classes to XML</a></p>
</li>
</ul>
<a id="BEICADBF" name="BEICADBF"></a><a id="TLADG294" name="TLADG294"></a>
<div class="sect2">
<h2 class="sect2"><font face="arial, helvetica, sans-serif" color="#330099">Binding JPA Relationships to XML</font></h2>
<p>The following exercise demonstrate show to use JAXB to derive an XML representation from a set of JPA entities, a process called "binding" (read about XML binding in <a href="#BEIGDBHI">Binding JPA Entities to XML</a>). These examples will show how to bind two common JPA relationships:</p>
<ul>
<li>
<p>Privately-owned relationships</p>
</li>
<li>
<p>Shared reference relationships</p>
</li>
</ul>
<p>to map an Employee entity to that employee's phone number, address, and department.</p>
<a id="BEIBJCIJ" name="BEIBJCIJ"></a><a id="TLADG295" name="TLADG295"></a>
<div class="sect3">
<h3 class="sect3"><font face="arial, helvetica, sans-serif" color="#330099">Task 1: Define the Accessor Type and Import Classes</font></h3>
<p>Since all of the following examples use the same accessor type, <code>FIELD</code>, define it at the package level by using the JAXB annotation <code>@XmlAccessorType</code>. At this point, you would also import the necessary classes:</p>
<pre xml:space="preserve" class="oac_no_warn">
<strong>@XmlAccessorType(XmlAccessType.FIELD)</strong>
package com.example.model;
<strong>import javax.xml.bind.annotation.XmlAccessType;</strong>
<strong>import javax.xml.bind.annotation.XmlAccessorType;</strong>
</pre></div>
<!-- class="sect3" -->
<a id="TLADG296" name="TLADG296"></a>
<div class="sect3"><!-- infolevel="all" infotype="General" --><a id="sthref97" name="sthref97"></a>
<h3 class="sect3"><font face="arial, helvetica, sans-serif" color="#330099">Task 2: Map Privately-Owned Relationships</font></h3>
<p>A "privately-owned" relationship occurs when the target object is only referenced by a single source object. This type of relationship can be either one-to-one and embedded or one-to-many.</p>
<p>This Task shows how to create bi-directional mappings for both of these types of relationships between the <code>Employee</code> entity and the <code>Address</code> and <code>PhoneNumber</code> entities.</p>
<a id="BEIJCIBI" name="BEIJCIBI"></a><a id="TLADG297" name="TLADG297"></a>
<div class="sect4">
<h4 class="sect4"><font face="arial, helvetica, sans-serif" color="#330099">Mapping a One-to-One and Embedded Relationship</font></h4>
<p>The JPA <code>@OneToOne</code> and <code>@Embedded</code> annotations indicate that only one instance of the source entity is able to refer to the same target entity instance. This example shows how to map the <code>Employee</code> entity to the <code>Address</code> entity and back. This is considered a one-to-one mapping because the employee can be associated with only one address. Since this relationship is bi-directional&mdash;that is, <code>Employee</code> points to <code>Address</code>, which must point back to <code>Employee</code>&mdash;it uses the EclipseLink extension <code>@XmlInverseReference</code> to represent the back-pointer.</p>
<p>To create the one-to-one and embedded mapping:</p>
<ol>
<li>
<p>Ensure that the accessor type <code>FIELD</code> has been defined at the package level, as described in <a href="#BEIBJCIJ">Task 1: Define the Accessor Type and Import Classes</a>.</p>
</li>
<li>
<p>Map one direction of the relationship, in this case, the <code>employee</code> property on <code>Address</code>, by inserting the <code>@OneToOne</code> annotation in the <code>Employee</code> entity:</p>
<pre xml:space="preserve" class="oac_no_warn">
<strong>@OneToOne(mappedBy="resident")</strong>
private <strong>Address</strong> residence;
</pre>
<p>The <code>mappedBy</code> argument indicates that the relationship is owned by the <code>resident</code> field.</p>
</li>
<li>
<p>Map the return direction&mdash;that is, the <code>address</code> property on <code>Employee</code>&mdash;by inserting the <code>@OneToOne</code> and <code>@XmlInverseMapping</code> annotations into the Address entity:</p>
<pre xml:space="preserve" class="oac_no_warn">
<strong>@OneToOne</strong>
@JoinColumn(name="E_ID")
<strong>@XmlInverseReference(mappedBy="residence")</strong>
private Employee resident;
</pre>
<p>The <code>mappedBy</code> field indicates that this relationship is owned by the <code>residence</code> field. <code>@JoinColumn</code> identifies the column that will contain the foreign key.</p>
</li>
</ol>
<p>The entities should look like those shown in <a href="#BEIJFCEG">Example 15-1</a> and <a href="#BEIEGBBE">Example 15-2</a>.</p>
<a id="TLADG298" name="TLADG298"></a>
<div class="sect4"><!-- infolevel="all" infotype="General" --><a id="sthref98" name="sthref98"></a>
<h4 class="sect4"><font face="arial, helvetica, sans-serif" color="#330099">Mapping a One-to-Many Relationship</font></h4>
<p>The JPA <code>@OneToMany</code> annotation indicates that a single instance of the source entity can refer to multiple instances of the same target entity. For example, one employee can have multiple phone numbers, such as a land line, a mobile number, a desired contact number, and an alternative workplace number. Each different number would be an instance of the <code>PhoneNumber</code> entity and a single <code>Employee</code> entity could point to each instance.</p>
<p>This Task maps the employee to one of that employee's phone numbers and back. Since the relationship between <code>Employee</code> and <code>PhoneNumber</code> is bi-directional, the example again uses the EclipseLink extension <code>@XmlInverseReference</code> to map the back-pointer.</p>
<p>To create a one-to-many mapping:</p>
<ol>
<li>
<p>Ensure that the accessor type <code>FIELD</code> has been defined at the package level, as described in <a href="#BEIBJCIJ">Task 1: Define the Accessor Type and Import Classes</a>.</p>
</li>
<li>
<p>Map one direction of the relationship, in this case, the employee property on <code>PhoneNumber</code>, by inserting the <code>@OneToMany</code> annotation in the <code>Employee</code> entity:</p>
<pre xml:space="preserve" class="oac_no_warn">
<strong>@OneToMany(mappedBy="contact")</strong>
private List&lt;<strong>PhoneNumber</strong>&gt; contactNumber;
</pre>
<p>The <code>mappedBy</code> field indicates that this relationship is owned by the <code>contact</code> field.</p>
</li>
<li>
<p>Map the return direction&mdash;that is, the phone number property on <code>Employee</code>&mdash;by inserting the <code>@ManyToOne</code> and <code>@XmlInverseMapping</code> annotations into the <code>PhoneNumber</code> entity:</p>
<pre xml:space="preserve" class="oac_no_warn">
<strong>@ManyToOne</strong>
@JoinColumn(name="E_ID", referencedColumnName = "E_ID")
<strong> @XmlInverseReference(mappedBy="contactNumber")</strong>
private <strong>Employee</strong> contact;
</pre>
<p>The <code>mappedBy</code> field indicates that this relationship is owned by the <code>contactNumber</code> field. The <code>@JoinColumn</code> annotation identifies the column that will contain the foreign key (<code>name="E_ID"</code>) and the column referenced by the foreign key (<code>referencedColumnName = "E_ID"</code>).</p>
</li>
</ol>
<p>The entities should look like those shown in <a href="#BEIJFCEG">Example 15-1</a> and <a href="#BEIEEFBA">Example 15-3</a>.</p>
</div>
<!-- class="sect4" --></div>
<!-- class="sect4" --></div>
<!-- class="sect3" -->
<a id="BEIEEFII" name="BEIEEFII"></a><a id="TLADG299" name="TLADG299"></a>
<div class="sect3">
<h3 class="sect3"><font face="arial, helvetica, sans-serif" color="#330099">Task 3: Map the Shared Reference Relationship</font></h3>
<p>A shared reference relationship occurs when target objects are referenced by multiple source objects. For example, a business might be segregated into multiple departments, such as IT, human resources, finance, and so on. Each of these departments has multiple employees of differing job descriptions, pay grades, locations, and so on. Managing departments and employees requires shared reference relationships.</p>
<p>Since a shared reference relationship cannot be safely represented as nesting in XML, we use key relationships. In order to leverage the ID fields on JPA entities, you need to use the EclipseLink JAXB <code>@XmlID</code> annotation on non-String fields and properties and <code>@XmlIDREF</code> on string fields and properties.</p>
<p>This section contains examples that show how to map a many-to-one shared reference relationship and a many-to-many shared reference relationship.</p>
<a id="TLADG300" name="TLADG300"></a>
<div class="sect4"><!-- infolevel="all" infotype="General" --><a id="sthref99" name="sthref99"></a>
<h4 class="sect4"><font face="arial, helvetica, sans-serif" color="#330099">Mapping a Many-to-One Shared Reference Relationship</font></h4>
<p>In a many-to-one mapping, one or more instances of the source entity are able to refer to the same target entity instance. This example demonstrates how to map an employee to one of that employee's multiple phone numbers.</p>
<p>To map a many-to-one shared reference relationship:</p>
<ol>
<li>
<p>Ensure that the accessor type <code>FIELD</code> has been defined at the package level, as described in <a href="#BEIBJCIJ">Task 1: Define the Accessor Type and Import Classes</a>.</p>
</li>
<li>
<p>Map one direction of the relationship, in this case the phone number property on <code>Employee</code>, by inserting the <code>@ManyToOne</code> annotation in the <code>PhoneNumber</code> entity:</p>
<pre xml:space="preserve" class="oac_no_warn">
<strong>@ManyToOne</strong>
@JoinColumn(name="E_ID", referencedColumnName = "E_ID")
@XmlIDREF
<strong>private Employee contact;</strong>
</pre>
<p>The <code>@JoinColumn</code> annotation identifies the column that will contain the foreign key (<code>name="E_ID"</code>) and the column referenced by the foreign key (<code>referencedColumnName = "E_ID"</code>). The <code>@XmlIDREF</code> annotation indicates that this will be the primary key for the corresponding table.</p>
</li>
<li>
<p>Map the return direction&mdash;that is, the employee property on PhoneNumber &mdash;by inserting the <code>@OneToMany</code> and <code>@XmlInverseMapping</code> annotations into the Address entity:</p>
<pre xml:space="preserve" class="oac_no_warn">
<strong>@OneToMany(mappedBy="contact")</strong>
<strong>@XmlInverseReference(mappedBy="contact")</strong>
private List&lt;PhoneNumber&gt; contactNumber;
</pre>
<p>The <code>mappedBy</code> field for both annotations indicates that this relationship is owned by the <code>contact</code> field.</p>
</li>
</ol>
<p>The entities should look like those shown in <a href="#BEIJFCEG">Example 15-1</a> and <a href="#BEIEEFBA">Example 15-3</a>.</p>
</div>
<!-- class="sect4" -->
<a id="TLADG301" name="TLADG301"></a>
<div class="sect4"><!-- infolevel="all" infotype="General" --><a id="sthref100" name="sthref100"></a>
<h4 class="sect4"><font face="arial, helvetica, sans-serif" color="#330099">Mapping a Many-to-Many Shared Reference Relationship</font></h4>
<p>The <code>@ManyToMany</code> annotation indicates that one or more instances of the source entity are able to refer to one or more target entity instances. Since the relationship between <code>Department</code> and <code>Employee</code> is bi-directional, this example again uses the EclipseLink's <code>@XmlInverseReference</code> annotation to represent the back-pointer.</p>
<p>To map a many-to-many shared reference relationship, do the following:</p>
<ol>
<li>
<p>Ensure that the accessor type <code>FIELD</code> has been defined at the package level, as described in <a href="#BEIBJCIJ">Task 1: Define the Accessor Type and Import Classes</a>.</p>
</li>
<li>
<p>Create a <code>Department</code> entity by inserting the following code:</p>
<pre xml:space="preserve" class="oac_no_warn">
@Entity
public class Department {
</pre></li>
<li>
<p>Under this entity define the many-to-many relationship and the entity's join table by inserting the following code:</p>
<pre xml:space="preserve" class="oac_no_warn">
@ManyToMany
@JoinTable(name="DEPT_EMP", joinColumns =
@JoinColumn(name="D_ID", referencedColumnName = "D_ID"),
inverseJoinColumns = @JoinColumn(name="E_ID",
referencedColumnName = "E_ID"))
</pre>
<p>This code creates a join table called <code>DEPT_EMP</code> and identifies the column that will contain the foreign key (<code>name="E_ID"</code>) and the column referenced by the foreign key (<code>referencedColumnName = "E_ID"</code>). Additionally, it identifies the primary table on the inverse side of the association.</p>
</li>
<li>
<p>Complete the initial mapping&mdash;in this case, the <code>Department</code> property <code>employee</code>&mdash;and make it a foreign key for this entity by inserting the following code:</p>
<pre xml:space="preserve" class="oac_no_warn">
@XmlIDREF
private List&lt;Employee&gt; member;
</pre></li>
<li>
<p>In the <code>Employee</code> entity created in <a href="#BEIJCIBI">Mapping a One-to-One and Embedded Relationship</a>, specifying that <code>eId</code> is the primary key for JPA (<code>@Id</code> annotation), and for JAXB (<code>@XmlID</code> annotation) by inserting the following code:</p>
<pre xml:space="preserve" class="oac_no_warn">
@Id
@Column(name="E_ID")
@XmlID
private BigDecimal eId;
</pre></li>
<li>
<p>Still within the <code>Employee</code> entity, complete the return mapping by inserting the following code:</p>
<pre xml:space="preserve" class="oac_no_warn">
@ManyToMany(mappedBy="member")
@XmlInverseReference(mappedBy="member")
private List&lt;Department&gt; team;
</pre></li>
</ol>
<p>The entities should look like those shown in <a href="#BEIJFCEG">Example 15-1</a> and <a href="#BEIHHJEA">Example 15-4</a>.</p>
</div>
<!-- class="sect4" --></div>
<!-- class="sect3" -->
<a id="TLADG302" name="TLADG302"></a>
<div class="sect3"><a id="sthref101" name="sthref101"></a>
<h3 class="sect3"><font face="arial, helvetica, sans-serif" color="#330099">JPA Entities</font></h3>
<p>Once the mappings are created, the entities should look like those in the following examples:</p>
<ul>
<li>
<p><a href="#BEIJFCEG">Example 15-1, "Employee Entity"</a></p>
</li>
<li>
<p><a href="#BEIEGBBE">Example 15-2, "Address Entity"</a></p>
</li>
<li>
<p><a href="#BEIEEFBA">Example 15-3, "PhoneNumber Entity"</a></p>
</li>
<li>
<p><a href="#BEIHHJEA">Example 15-4, "Department Entity"</a></p>
</li>
</ul>
<div align="center">
<div class="inftblnote"><br />
<table class="Note oac_no_warn" summary="" border="1" width="80%" frame="hsides" rules="groups" cellpadding="3" cellspacing="0">
<tbody>
<tr>
<td align="left">
<p class="note"><img src="../../dcommon/images/note_icon.png" width="16" height="16" alt="Note" style="vertical-align:middle;padding-right:5px;" />Note:</p>
<p>In order to save space, package names, import statements, and the get/set methods have been omitted from the code examples. All examples use standard JPA annotations.</p>
</td>
</tr>
</tbody>
</table>
<br /></div>
<!-- class="inftblnote" --></div>
<div class="example"><a id="BEIJFCEG" name="BEIJFCEG"></a><a id="TLADG303" name="TLADG303"></a>
<p><strong><em><font face="arial, helvetica, sans-serif">Example 15-1 Employee Entity</font></em></strong></p>
<pre xml:space="preserve" class="oac_no_warn">
@Entity
public class <strong>Employee</strong> {
@Id
@Column(name="E_ID")
private BigDecimal eId;
private String name;
@OneToOne(mappedBy="resident")
private Address residence;
@OneToMany(mappedBy="contact")
private List&lt;PhoneNumber&gt; contactNumber;
@ManyToMany(mappedBy="member")
private List&lt;Department&gt; team;
}
</pre></div>
<!-- class="example" -->
<div class="example"><a id="BEIEGBBE" name="BEIEGBBE"></a><a id="TLADG304" name="TLADG304"></a>
<p><strong><em><font face="arial, helvetica, sans-serif">Example 15-2 Address Entity</font></em></strong></p>
<pre xml:space="preserve" class="oac_no_warn">
@Entity
public class <strong>Address</strong> {
@Id
@Column(name="E_ID", insertable=false, updatable=false)
private BigDecimal eId;
private String city;
private String street;
@OneToOne
@JoinColumn(name="E_ID")
private Employee resident;
}
</pre></div>
<!-- class="example" -->
<div class="example"><a id="BEIEEFBA" name="BEIEEFBA"></a><a id="TLADG305" name="TLADG305"></a>
<p><strong><em><font face="arial, helvetica, sans-serif">Example 15-3 PhoneNumber Entity</font></em></strong></p>
<pre xml:space="preserve" class="oac_no_warn">
@Entity
@Table(name="PHONE_NUMBER")
public class <strong>PhoneNumber</strong> {
@Id
@Column(name="P_ID")
private BigDecimal pId;
@ManyToOne
@JoinColumn(name="E_ID", referencedColumnName = "E_ID")
private Employee contact;
private String num;
}
</pre></div>
<!-- class="example" -->
<div class="example"><a id="BEIHHJEA" name="BEIHHJEA"></a><a id="TLADG306" name="TLADG306"></a>
<p><strong><em><font face="arial, helvetica, sans-serif">Example 15-4 Department Entity</font></em></strong></p>
<pre xml:space="preserve" class="oac_no_warn">
@Entity
public class <strong>Department</strong> {
@Id
@Column(name="D_ID")
private BigDecimal dId;
private String name;
@ManyToMany
@JoinTable(name="DEPT_EMP", joinColumns =
@JoinColumn(name="D_ID", referencedColumnName = "D_ID"),
inverseJoinColumns = @JoinColumn(name="E_ID",
referencedColumnName = "E_ID"))
private List&lt;Employee&gt; member;
}
</pre></div>
<!-- class="example" --></div>
<!-- class="sect3" --></div>
<!-- class="sect2" -->
<a id="BEIIHFJG" name="BEIIHFJG"></a><a id="TLADG307" name="TLADG307"></a>
<div class="sect2">
<h2 class="sect2"><font face="arial, helvetica, sans-serif" color="#330099">Binding Compound Primary Keys to XML</font></h2>
<p>When a JPA entity has compound primary keys, you can bind it by using JAXB annotations and certain EclipseLink extensions, as shown in the following example.</p>
<a id="TLADG308" name="TLADG308"></a>
<div class="sect3"><a id="sthref102" name="sthref102"></a>
<h3 class="sect3"><font face="arial, helvetica, sans-serif" color="#330099">Task1: Define the XML Accessor Type</font></h3>
<p>Define the accessor type as <code>FIELD</code>, as described in <a href="#BEIBJCIJ">Task 1: Define the Accessor Type and Import Classes</a></p>
</div>
<!-- class="sect3" -->
<a id="TLADG309" name="TLADG309"></a>
<div class="sect3"><!-- infolevel="all" infotype="General" --><a id="sthref103" name="sthref103"></a>
<h3 class="sect3"><font face="arial, helvetica, sans-serif" color="#330099">Task 2: Create the Target Object</font></h3>
<p>To create the target object, do the following:</p>
<ol>
<li>
<p>Create an <code>Employee</code> entity with a composite primary key class called <code>EmployeeID</code> to map to multiple fields or properties of the entity:</p>
<pre xml:space="preserve" class="oac_no_warn">
@Entity
<strong>@IdClass(EmployeeId.class)</strong>
public class Employee {
</pre></li>
<li>
<p>Specify the first primary key, eId, of the entity and map it to a column:</p>
<pre xml:space="preserve" class="oac_no_warn">
@Id
@Column(name="E_ID")
@XmlID
private BigDecimal eId;
</pre></li>
<li>
<p>Specify the second primary key, country. In this instance, you need to use <code>@XmlKey</code> to identify the primary key because only one property&mdash; <code>eId</code>&mdash;can be annotated with the <code>@XmlID</code>.</p>
<pre xml:space="preserve" class="oac_no_warn">
@Id
@XmlKey
private String country;
</pre>
<p>The <code>@XmlKey</code> annotation marks a property as a key that will be referenced by using a key-based mapping via the <code>@XmlJoinNode</code> annotation in the source object. This is similar to the <code>@XmlKey</code> annotation except it doesn't require the property be bound to the schema type ID. This is a typical application of the <code>@XmlKey</code> annotation.</p>
</li>
<li>
<p>Create a many-to-one mapping of the <code>Employee</code> property on <code>PhoneNumber</code> by inserting the following code:</p>
<pre xml:space="preserve" class="oac_no_warn">
<strong>@OneToMany(mappedBy="contact")</strong>
@XmlInverseReference(mappedBy="contact")
<strong>private List&lt;PhoneNumber&gt; contactNumber;</strong>
</pre></li>
</ol>
<p>The Employee entity should look like <a href="#BEIDFDDJ">Example 15-5</a></p>
<div class="example"><a id="BEIDFDDJ" name="BEIDFDDJ"></a><a id="TLADG310" name="TLADG310"></a>
<p><strong><em><font face="arial, helvetica, sans-serif">Example 15-5 Employee Entity with Compound Primary Keys</font></em></strong></p>
<pre xml:space="preserve" class="oac_no_warn">
@Entity
@IdClass(EmployeeId.class)
public class Employee {
@Id
@Column(name="E_ID")
@XmlID
private BigDecimal eId;
@Id
@XmlKey
private String country;
@OneToMany(mappedBy="contact")
@XmlInverseReference(mappedBy="contact")
private List&lt;PhoneNumber&gt; contactNumber;
}
public class EmployeeId {
public BigDecimal eId;
public String country;
public EmployeeId(BigDecimal eId, String country) {
this.id = id;
this.country = country;;
}
public boolean equals(Object other) {
if (other instanceof EmployeeId) {
final EmployeeId otherEmployeeId = (EmployeeId) other;
return (otherEmployeeId.eId.equals(eId) &amp;&amp; otherEmployeeId.country.equals(country));
}
return false;
}
}
</pre></div>
<!-- class="example" --></div>
<!-- class="sect3" -->
<a id="TLADG311" name="TLADG311"></a>
<div class="sect3"><!-- infolevel="all" infotype="General" --><a id="sthref104" name="sthref104"></a>
<h3 class="sect3"><font face="arial, helvetica, sans-serif" color="#330099">Task 3: Create the Source Object</font></h3>
<p>This Task creates the source object, the <code>PhoneNumber</code> entity. Because the target object has a compound key, we need to use the EclipseLink's <code>@XmlJoinNodes</code> annotation to set up the mapping.</p>
<p>To create the source object:</p>
<ol>
<li>
<p>Create the <code>PhoneNumber</code> entity:</p>
<pre xml:space="preserve" class="oac_no_warn">
@Entity
public class PhoneNumber {
</pre></li>
<li>
<p>Create a many-to-one relationship and define the join columns:</p>
<pre xml:space="preserve" class="oac_no_warn">
@ManyToOne
@JoinColumns({
@JoinColumn(name="E_ID", referencedColumnName = "E_ID"),
@JoinColumn(name="E_COUNTRY", referencedColumnName = "COUNTRY")
})
</pre></li>
<li>
<p>Set up the mapping by using the EclipseLink's <code>@XmlJoinNodes</code> annotation</p>
<pre xml:space="preserve" class="oac_no_warn">
@XmlJoinNodes( {
@XmlJoinNode(xmlPath="contact/id/text()", referencedXmlPath="id/text()"),
@XmlJoinNode(xmlPath="contact/country/text()", referencedXmlPath="country/text()")
})
</pre></li>
<li>
<p>Define the <code>contact</code> property:</p>
<pre xml:space="preserve" class="oac_no_warn">
private Employee contact;
}
</pre></li>
</ol>
<p>The target object should look like <a href="#BEIFBGAG">Example 15-6</a>.</p>
<div class="example"><a id="BEIFBGAG" name="BEIFBGAG"></a><a id="TLADG312" name="TLADG312"></a>
<p><strong><em><font face="arial, helvetica, sans-serif">Example 15-6 PhoneNumber Entity</font></em></strong></p>
<pre xml:space="preserve" class="oac_no_warn">
@Entity
public class PhoneNumber {
@ManyToOne
@JoinColumns({
@JoinColumn(name="E_ID", referencedColumnName = "E_ID"),
@JoinColumn(name="E_COUNTRY", referencedColumnName = "COUNTRY")
})
@XmlJoinNodes( {
@XmlJoinNode(xmlPath="contact/id/text()", referencedXmlPath="id/text()"),
@XmlJoinNode(xmlPath="contact/country/text()", referencedXmlPath="country/text()")
})
private Employee contact;
}
</pre></div>
<!-- class="example" --></div>
<!-- class="sect3" --></div>
<!-- class="sect2" -->
<a id="BEIECBGA" name="BEIECBGA"></a><a id="TLADG313" name="TLADG313"></a>
<div class="sect2">
<h2 class="sect2"><font face="arial, helvetica, sans-serif" color="#330099">Binding Embedded ID Classes to XML</font></h2>
<p>An embedded ID defines a separate <code>Embeddable</code> Java class to contain the entity's primary key. It is defined through the <code>@EmbeddedId</code> annotation.The embedded ID's <code>Embeddable</code> class must define each id attribute for the entity using basic mappings. All attributes in the embedded Id's <code>Embeddable</code> are assumed to be part of the primary key. This exercise shows how to derive an XML representation from a set of JPA entities using JAXB when a JPA entity has an embedded ID class.</p>
<a id="TLADG314" name="TLADG314"></a>
<div class="sect3"><a id="sthref105" name="sthref105"></a>
<h3 class="sect3"><font face="arial, helvetica, sans-serif" color="#330099">Task1: Define the XML Accessor Type</font></h3>
<p>Define the XML accessor type as <code>FIELD</code>, as described in <a href="#BEIBJCIJ">Task 1: Define the Accessor Type and Import Classes</a></p>
</div>
<!-- class="sect3" -->
<a id="BEIDGBIA" name="BEIDGBIA"></a><a id="TLADG315" name="TLADG315"></a>
<div class="sect3"><!-- infolevel="all" infotype="General" -->
<h3 class="sect3"><font face="arial, helvetica, sans-serif" color="#330099">Task 2: Create the Target Object</font></h3>
<p>The target object is an entity called <code>Employee</code> and contains the mapping for an employee's contact phone number. Creating this target object requires implementing a <code>DescriptorCustomizer</code> interface, so you must include EclipseLink's <code>@XmlCustomizer</code> annotation Also, since the relationship is bidirectional, you must also implement the <code>@XmlInverseReference</code>. annotation.</p>
<p>To create the target object:</p>
<ol>
<li>
<p>Create the <code>Employee</code> entity. Use the <code>@IdClass</code> annotation to specify that the <code>EmployeeID</code> class will be mapped to multiple properties of the entity.</p>
<pre xml:space="preserve" class="oac_no_warn">
@Entity
<strong>@IdClass(EmployeeId.class)</strong>
public class Employee {
}
</pre></li>
<li>
<p>Define the <code>id</code> property and make it embeddable.</p>
<pre xml:space="preserve" class="oac_no_warn">
@EmbeddedId
@XmlPath(".");
private EmployeeId id;
</pre></li>
<li>
<p>Define a one-to-many mapping&mdash;in this case, the <code>employee</code> property on <code>PhoneNumber</code>. Because the relationship is bi-directional, use <code>@XmlInverseReference</code> to define the return mapping. Both of these relationships will be owned by the contact field, as indicated by the <code>mappedBy</code> argument.</p>
<pre xml:space="preserve" class="oac_no_warn">
@OneToMany(mappedBy="contact")
@XmlInverseReference(mappedBy="contact")
private List&lt;PhoneNumber&gt; contactNumber;
</pre></li>
</ol>
<p>The completed target object should look like <a href="#BEIDAGDJ">Example 15-7</a>.</p>
<div class="example"><a id="BEIDAGDJ" name="BEIDAGDJ"></a><a id="TLADG316" name="TLADG316"></a>
<p><strong><em><font face="arial, helvetica, sans-serif">Example 15-7 Employee Entity as Target Object</font></em></strong></p>
<pre xml:space="preserve" class="oac_no_warn">
@Entity
@IdClass(EmployeeId.class)
@XmlCustomizer(EmployeeCustomizer.class)
public class Employee {
@EmbeddedId
private EmployeeId id;
@OneToMany(mappedBy="contact")
@XmlInverseReference(mappedBy="contact")
private List&lt;PhoneNumber&gt; contactNumber;
}
</pre></div>
<!-- class="example" --></div>
<!-- class="sect3" -->
<a id="TLADG319" name="TLADG319"></a>
<div class="sect3"><a id="sthref106" name="sthref106"></a>
<h3 class="sect3"><font face="arial, helvetica, sans-serif" color="#330099">Task 3: Create the Source Object</font></h3>
<p>The source object in this example has a compound key, so you must mark the field <code>@XmlTransient</code> to prevent a key from being mapped by itself. Use EclipseLink's <code>@XmlCustomizer</code> annotation to set up the mapping.</p>
<p>To create the source object, do the following:</p>
<ol>
<li>
<p>Create the <code>PhoneNumber</code> entity.</p>
<pre xml:space="preserve" class="oac_no_warn">
@Entity
public class PhoneNumber {
}
</pre></li>
<li>
<p>Create a many-to-one mapping and define the join columns.</p>
<pre xml:space="preserve" class="oac_no_warn">
@ManyToOne
@JoinColumns({
@JoinColumn(name="E_ID", referencedColumnName = "E_ID"),
@JoinColumn(name="E_COUNTRY", referencedColumnName = "COUNTRY")
})
</pre></li>
<li>
<p>Define the XML nodes for the mapping, using the EclipseLink <code>@XmlJoinNodes</code> annotation extension. If the target object had a <em>single</em> ID, you would use the <code>@XmlIDREF</code> annotation.</p>
</li>
</ol>
<pre xml:space="preserve" class="oac_no_warn">
@XmlJoinNodes( { @XmlJoinNode(xmlPath="contact/id/text()", referencedXmlPath="id/text()"), @XmlJoinNode(xmlPath="contact/country/text()", referencedXmlPath="country/text()") })
private Employee contact;
</pre>
<p>The completed <code>PhoneNumber</code> class should look like <a href="#BEIGJACE">Example 15-8</a>.</p>
<div class="example"><a id="BEIGJACE" name="BEIGJACE"></a><a id="TLADG320" name="TLADG320"></a>
<p><strong><em><font face="arial, helvetica, sans-serif">Example 15-8 PhoneNumber Class as Source Object</font></em></strong></p>
<pre xml:space="preserve" class="oac_no_warn">
@Entity
public class PhoneNumber {
@ManyToOne
@JoinColumns({
@JoinColumn(name="E_ID", referencedColumnName = "E_ID"),
@JoinColumn(name="E_COUNTRY", referencedColumnName = "COUNTRY")
})
@XmlJoinNodes( {
@XmlJoinNode(xmlPath="contact/id/text()", referencedXmlPath="id/text()"),
@XmlJoinNode(xmlPath="contact/country/text()", referencedXmlPath="country/text()")
})
private Employee contact;
}
</pre></div>
<!-- class="example" --></div>
<!-- class="sect3" -->
<a id="TLADG321" name="TLADG321"></a>
<div class="sect3"><!-- infolevel="all" infotype="General" --><a id="sthref107" name="sthref107"></a>
<h3 class="sect3"><font face="arial, helvetica, sans-serif" color="#330099">Task 5: Implement the DescriptorCustomizer as PhoneNumberCustomizer Class</font></h3>
<p>Code added in Task 4 indicated the need to create the XMLObjectReferenceMappings to the new values. This requires to implementing the <code>DescriptorCustomizer</code> as the <code>PhoneNumberCustomizer</code> and adding the multiple key mappings. To do this:</p>
<ol>
<li>
<p>Implement <code>DescriptorCustomizer</code> as <code>PhoneNumberCustomizer</code>. Be sure to import <code>org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping</code>:</p>
<pre xml:space="preserve" class="oac_no_warn">
import org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping;
<strong>public class PhoneNumberCustomizer implements DescriptorCustomizer {</strong>
</pre></li>
<li>
<p>In the <code>customize</code> method, update the following mappings:</p>
<ul>
<li>
<p><code>contactMapping.setAttributeName</code> to <code>"contact"</code>.</p>
</li>
<li>
<p><code>contactMapping.addSourceToTargetKeyFieldAssociation</code> to <code>"contact/@eID", "eId/text()"</code>.</p>
</li>
<li>
<p><code>contactMapping.addSourceToTargetKeyFieldAssociation</code> to <code>"contact/@country", "country/text()"</code>.</p>
</li>
</ul>
</li>
</ol>
<p><code>PhoneNumberCustomizer</code> should look like <a href="#BEIFCHBH">Example 15-9</a>.</p>
<div class="example"><a id="BEIFCHBH" name="BEIFCHBH"></a><a id="TLADG322" name="TLADG322"></a>
<p><strong><em><font face="arial, helvetica, sans-serif">Example 15-9 PhoneNumber Customizer with Updated Key Mappings</font></em></strong></p>
<pre xml:space="preserve" class="oac_no_warn">
import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping;
public class PhoneNumberCustomizer implements DescriptorCustomizer {
public void customize(ClassDescriptor descriptor) throws Exception {
XMLObjectReferenceMapping contactMapping = new XMLObjectReferenceMapping();
contactMapping.setAttributeName("contact");
contactMapping.setReferenceClass(Employee.class);
contactMapping.addSourceToTargetKeyFieldAssociation("contact/@eID", "eId/text()");
contactMapping.addSourceToTargetKeyFieldAssociation("contact/@country", "country/text()");
descriptor.addMapping(contactMapping);
}
}
</pre></div>
<!-- class="example" --></div>
<!-- class="sect3" --></div>
<!-- class="sect2" -->
<a id="BEIBJBFA" name="BEIBJBFA"></a><a id="TLADG323" name="TLADG323"></a>
<div class="sect2">
<h2 class="sect2"><font face="arial, helvetica, sans-serif" color="#330099">Using the EclipseLink XML Binding Document</font></h2>
<p>As demonstrated in the preceding examples, EclipseLink implements the standard JAXB annotations to map JPA entities to an XML representation. You can also express metadata by using the EclipseLink XML Bindings document. Not only can you use XML bindings to separate your mapping information from your actual Java class but you can also use it for more advanced metadata tasks such as:</p>
<ul>
<li>
<p>Augmenting or overriding existing annotations with additional mapping information.</p>
</li>
<li>
<p>Specifying all mapping information externally, without using any Java annotations.</p>
</li>
<li>
<p>Defining your mappings across multiple Bindings documents.</p>
</li>
<li>
<p>Specifying "virtual" mappings that do not correspond to concrete Java fields</p>
</li>
</ul>
<p>For more information about using the XML Bindings document, see XML Bindings in the JAXB/MOXy documentation at <code><a href="http://wiki.eclipse.org/EclipseLink/UserGuide/MOXy/Runtime/XML_Bindings">http://wiki.eclipse.org/EclipseLink/UserGuide/MOXy/Runtime/XML_Bindings</a></code>.</p>
</div>
<!-- class="sect2" --></div>
<!-- class="sect1" --></div>
<!-- class="ind" -->
<!-- Start Footer -->
<div class="footer">
<hr />
<table class="simple oac_no_warn" summary="" cellspacing="0" cellpadding="0" width="100%">
<col width="33%" />
<col width="*" />
<col width="33%" />
<tr>
<td valign="bottom">
<table class="navigation simple oac_no_warn" summary="" cellspacing="0" cellpadding="0" width="100" align="center">
<col width="*" />
<col width="48%" />
<col width="48%" />
<tr>
<td>&nbsp;</td>
<td align="center"><a href="jpatoxml001.htm"><img src="../../dcommon/images/larrow.png" alt="Previous" border="0" height="16" width="16" /></a></td>
<td align="center"><a href="jpatoxml003.htm"><img src="../../dcommon/images/rarrow.png" alt="Next" border="0" height="16" width="16" /></a></td>
</tr>
</table>
</td>
<td align="center" width="34%"><a href="http://www.eclipse.org/eclipselink/" title="EclipseLink home"><img src="../../dcommon/images/ellogo.png" alt="EclipseLink" width="150" border="0" /></a><br />
<font size="-2">Copyright&nbsp;&copy;&nbsp;2014,&nbsp;Oracle&nbsp;and/or&nbsp;its&nbsp;affiliates.&nbsp;All&nbsp;rights&nbsp;reserved.</font> <a href="../../dcommon/html/cpyr.htm"><br />
<td valign="bottom" align="right">
<table class="simple oac_no_warn" summary="" cellspacing="0" cellpadding="0" width="225">
<tr>
<td>&nbsp;</td>
<td align="center" valign="top"><a href="toc.htm"><img src="../../dcommon/images/contents.png" alt="Go To Table Of Contents" border="0" height="16" width="16" /><br />
</td><td>&nbsp;</td><td align="center"><a href="../../" target="_top" class="external text" title="Search" rel="nofollow"><img src="../../dcommon/images/search.png" alt="Search" style="border:0;" /><br /><span class="mini"></span></a></td><td>&nbsp;</td><td align="center"><a href="../eclipselink_otlcg.pdf" title="PDF" target="_blank"><img src="../../dcommon/images/pdf_icon.png" style="padding-right:5px;border:0" alt="PDF"></a></td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<!-- class="footer" -->
<div id="copyright">Copyright &copy; 2014 by The Eclipse Foundation under the <a href="http://www.eclipse.org/org/documents/epl-v10.php">Eclipse Public License (EPL)</a><br /> <script type="text/javascript">var LastUpdated = document.lastModified;document.writeln ("Updated: " + LastUpdated);</script> </div><!-- START: Analytics --><script type="text/javascript"> var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-1608008-2']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); </script><!-- END: Analytics --><!-- START: Sharethis --><script>var options={ "publisher": "e2fe9e07-fab6-4f84-83ea-0991b429842c", "position": "right", "ad": { "visible": false, "openDelay": 5, "closeDelay": 0}};var st_hover_widget = new sharethis.widgets.hoverbuttons(options);</script><!-- END: Sharethis --></body>
</html>