Jump to: navigation, search

EclipseLink/UserGuide/MOXy/Relationships/Shared Reference/Keys and Foreign Keys/Composite Key

EclipseLink MOXy

link="http://wiki.eclipse.org/EclipseLink"
EclipseLink
Website
Download
Community
Mailing ListForumsIRC
Bugzilla
Open
Help Wanted
Bug Day
Contribute
Browse Source


Mapping Composite Key Relationships

If the objects that you want to map have multi-part keys (i.e., a combination of fields that determines uniqueness), you can use EclipseLink's @XmlKey and @XmlJoinNodes to set up this relationship.

One or more @XmlKey annotations can be used to declare the primary keys in a given class. For a single key, either @XmlID or @XmlKey can be used. For composite primary keys, multiple @XmlKey annotations can be used, or a single @XmlID can be combined with one or more @XmlKey annotations.

Idea.png
Composite Keys can be useful when using JAXB to map JPA entities. For more information see Converting JPA entities to/from XML (via JAXB).


In this example, each Employee has one manager but multiple reports, and Employees are uniquely identified by the combination of their id and name fields.

package example;
 
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;
 
@XmlAccessorType(XmlAccessType.FIELD)
public class Employee {
    @XmlID
    @XmlAttribute
    private Integer id;
 
    @XmlKey
    @XmlAttribute
    private String name;
 
    @XmlJoinNodes( {
        @XmlJoinNode(xmlPath = "manager/@id", referencedXmlPath = "@id"),
        @XmlJoinNode(xmlPath = "manager/@name", referencedXmlPath = "@name") })
    public Employee manager;
 
    @XmlJoinNodes( {
        @XmlJoinNode(xmlPath = "report/@id", referencedXmlPath = "@id"),
        @XmlJoinNode(xmlPath = "report/@name", referencedXmlPath = "@name") })
    public List<Employee> reports = new ArrayList<Employee>();
 
    ...
}

The following example shows how to define this mapping information in EclipseLink's OXM metadata format.

...
<java-type name="Employee">
    <java-attributes>
        <xml-attribute java-attribute="id" xml-id="true" />
        <xml-attribute java-attribute="name" xml-key="true" />
        <xml-join-nodes java-attribute="manager">
            <xml-join-node xml-path="manager/@id" referenced-xml-path="@id" />
            <xml-join-node xml-path="manager/@name" referenced-xml-path="@name" />
        </xml-join-nodes>
        <xml-join-nodes java-attribute="reports" container-type="java.util.ArrayList">
            <xml-join-node xml-path="report/@id" referenced-xml-path="@id" />
            <xml-join-node xml-path="report/@name" referenced-xml-path="@name" />
        </xml-join-nodes>
    </java-attributes>
</java-type>
...

This would produce the following XML:

<company>
   <employee id="1" name="Jane Doe">
      <report id="2" name="John Smith"/>
      <report id="3" name="Anne Jones"/>
   </employee>
   <employee id="2" name="John Smith">
      <manager id="1" name="Jane Doe"/>
   </employee>
   <employee id="3" name="Anne Jones">
      <manager id="1" name="Jane Doe"/>
   </employee>
</company>


Eclipselink-logo.gif
Version: 2.2.0 DRAFT
Other versions...