Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "EclipseLink/UserGuide/MOXy/Relationships/Privately Owned/One-to-One"

(Working with Null Values)
Line 37: Line 37:
 
<source lang="java">
 
<source lang="java">
 
@XmlRootElement
 
@XmlRootElement
 +
@XmlAccessorType(XmlAccessType.FIELD)
 
public class Customer {
 
public class Customer {
 
   @XmlElement(name="phone-number")
 
   @XmlElement(name="phone-number")
 
   private PhoneNumber phoneNumber;
 
   private PhoneNumber phoneNumber;
  
   public void setPhoneNumber(PhoneNumber value) {
+
   ...
      this.phoneNumber = value;
+
  }
+
 
}
 
}
  
 +
@XmlAccessorType(XmlAccessType.FIELD)
 
public class PhoneNumber {
 
public class PhoneNumber {
 
   @XmlElement(name="area-code")
 
   @XmlElement(name="area-code")
Line 54: Line 54:
 
   private Integer extension;
 
   private Integer extension;
  
  public void setAreaCode(Integer value) {
 
      this.areaCode = value;
 
  }
 
 
   ...
 
   ...
 
}
 
}
Line 88: Line 85:
 
<source lang="java">
 
<source lang="java">
 
@XmlRootElement
 
@XmlRootElement
 +
@XmlAccessorType(XmlAccessType.FIELD)
 
public class Customer {
 
public class Customer {
 
   @XmlPath(".")
 
   @XmlPath(".")
 
   private PhoneNumber phoneNumber;
 
   private PhoneNumber phoneNumber;
  
  public void setPhoneNumber(PhoneNumber value) {
 
      this.phoneNumber = value;
 
  }
 
 
   ...
 
   ...
 
}
 
}
Line 174: Line 169:
  
 
@XmlRootElement
 
@XmlRootElement
 +
@XmlAccessorType(XmlAccessType.FIELD)
 
public class Customer {
 
public class Customer {
 
   private String id;
 
   private String id;
Line 183: Line 179:
 
   private String accountNumber;
 
   private String accountNumber;
  
  public void setId(String value) {
 
      this.id = value;
 
  }
 
 
   ...
 
   ...
 
}
 
}

Revision as of 16:46, 5 January 2011

EclipseLink MOXy

Eclipselink-logo.gif
EclipseLink
Website
Download
Community
Mailing ListForumsIRCmattermost
Issues
OpenHelp WantedBug Day
Contribute
Browse Source

Mapping One-to-One Relationships

This section demonstrates several ways to map a one-to-one relationship between objects.

Mapping to a Complex Type

Given the XML schema in this example, the figure below illustrates a one-to-one relationship between two complex types.

<?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:element name="address" type="address-type"/>
   </xsd:complexType>
 
   <xsd:complexType name="phone-type">
      <xsd:element name="area-code" type="xsd:int"/>
      <xsd:element name="number" type="xsd:int"/>
      <xsd:element name="extension" type="xsd:int"/>
   </xsd:complexType>
 
</xsd:schema>

Onetoone.png

The following example shows how to annotate your Java class to obtain this mapping with EclipseLink. All that is needed is the standard JAXB @XmlElement annotation.

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
   @XmlElement(name="phone-number")
   private PhoneNumber phoneNumber;
 
   ...
}
 
@XmlAccessorType(XmlAccessType.FIELD)
public class PhoneNumber {
   @XmlElement(name="area-code")
   private Integer areaCode;
 
   private Integer number;
 
   private Integer extension;
 
   ...
}

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

...
<java-type name="Customer">
   <xml-root-element name="customer"/>
   <java-attributes>
      <xml-element java-attribute="phoneNumber" name="phone-number" type="PhoneNumber"/>
   </java-attributes>
</java-type>
 
<java-type name="PhoneNumber">
   <java-attributes>
      <xml-value java-attribute="areaCode" name="area-code" type="java.lang.Integer"/>
      <xml-value java-attribute="number" type="java.lang.Integer"/>
      <xml-value java-attribute="extension" type="java.lang.Integer"/>
   </java-attributes>
</java-type>
...

"Self" Mappings

EclipseLink allows you to configure your one-to-one mapping such that the data from the target object will appear inside the source object's XML element. Using the example above, this means that the "PhoneNumber" information would appear directly under the "customer" element, and not wrapped in a "phone-number" element. This is referred to as a "self" mapping, and is achieved by setting the target object's XPath to "." (dot). The following example demonstrates a self mapping declared in annotations.

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
   @XmlPath(".")
   private PhoneNumber phoneNumber;
 
   ...
}
 
public class PhoneNumber {
   ...
}

The example below shows a self mapping defined on EclipseLink OXM metadata format.

...
<java-type name="Customer">
   <xml-root-element name="customer"/>
   <java-attributes>
      <xml-element java-attribute="phoneNumber" type="PhoneNumber" xml-path="."/>
   </java-attributes>
</java-type>
 
<java-type name="PhoneNumber">
   ...
</java-type>
...

Using a self mapping, the following XML will be produced:

<customer>
   <area-code>613</area-code>
   <number>2883000</number>
   <extension>1547</extension>
</customer>

Working with Null Values

Eclipselink offers several ways to configure its handling of null values in both Java and XML. For example, your XML may use xsi:nil to represent a null value (e.g. <first-name xsi:nil="true"/>), or it might simply use an empty element (e.g. <first-name></first-name>). On the Java side, you may want to specify exactly how a null value should be written to XML (nil or empty node). You can even specify an "isSet" method, to differentiate between values that were explicitly set to null versus values which are null due to being unset.

Consider the following schema:

<?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:element name="id" type="xsd:string"/>
      <xsd:element name="name" type="xsd:string"/>
      <xsd:element name="account-number" type="xsd:string" nillable="true"/>
   </xsd:complexType>
 
</xsd:schema>

An example instance document might look like:

<customer>
   <id/>
   <name>Jon Smith</name>
   <account-number xsi:nil="true"/>
</customer>

For this example, we would like:

  • Empty id tags to correspond to null in Java
  • Empty name tags to correspond to "" (empty string) in Java (this is EclipseLink's default null-handling behavior)
  • A nil account-number to correspond to null in Java

To achieve this behavior in EclipseLink, our mappings can be defined using annotations as follows:

import org.eclipse.persistence.oxm.annotations.XmlNullPolicy;
import org.eclipse.persistence.oxm.annotations.XmlMarshalNullRepresentation;
 
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
   private String id;
 
   private String name;
 
   @XmlElement(name="account-number")
   @XmlNullPolicy(xsiNilRepresentNull="true" nullRepresentationForXml=XmlMarshalNullRepresentation.XSI_NIL)
   private String accountNumber;
 
   ...
}

Here, we have specified that xsi:nil in XML should represent null in Java, and conversely, that null in Java should be represented by xsi:nil in XML.

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

Back to the top