This section illustrates how to map one-to-many relationships with EclipseLink.
The schema in Example 6-8 a typical one-to-many (1:M) relationship between Customer and PhoneNumber, as shown in Figure 6-2.
Example 6-8 Sample XML Mapping
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customer" type="customer-type"/>
<xsd:complexType name="customer-type">
<xsd:sequence>
<xsd:element name="first-name" type="xsd:string"/>
<xsd:element name="last-name" type="xsd:string"/>
<xsd:element name="phone-number" type="phone-type" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="phone-type">
<xsd:sequence>
<xsd:attribute name="type" type="xsd:string"/>
<xsd:element name="number" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Example 6-9 shows how to annotate your Java class to obtain this mapping with EclipseLink. The standard JAXB @XmlElement annotation, when used on a Collection or array field, can achieve this.
Example 6-9 Using the @XmlElement Annotation
package example;
import jakarta.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlElement(name="first-name")
private String firstName;
@XmlElement(name="last-name")
private String lastName;
@XmlElement(name="phone-number")
private List<PhoneNumber> phoneNumbers;
...
}
package example;
import jakarta.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class PhoneNumber {
@XmlAttribute
private String type;
private Integer number;
...
}
Example 6-10 shows how to define your mapping information in EclipseLink's OXM metadata format.
Example 6-10 Sample XML Mapping
...
<java-type name="Customer">
<xml-root-element name="customer"/>
<java-attributes>
<xml-element java-attribute="firstName" name="first-name" type="java.lang.String"/>
<xml-element java-attribute="lastName" name="last-name" type="java.lang.String"/>
<xml-element java-attribute="phoneNumbers" name="phone-number" type="PhoneNumber" container-type="java.util.ArrayList"/>
</java-attributes>
</java-type>
<java-type name="PhoneNumber">
<java-attributes>
<xml-attribute java-attribute="type" type="java.lang.String"/>
<xml-value java-attribute="number" type="java.lang.Integer"/>
</java-attributes>
</java-type>
...
To make the elements of the Collection appear inside a grouping element, you can use @XmlElementWrapper:
Example 6-11 Using the @XmlElementWrapper Annotation
package example;
import jakarta.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlElement(name = "phone-number")
@XmlElementWrapper(name="phone-numbers")
private List<PhoneNumber> phoneNumbers;
...
}
This will produce the following XML:
<customer>
<first-name>Bob</first-name>
<last-name>Smith</last-name>
<phone-numbers>
<phone-number type="Home">
<number>5559827222</number>
</phone-number>
<phone-number type="Work">
<number>5558872216</number>
</phone-number>
</phone-numbers>
</customer>