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/DesignDocs/317962/Phase3"

(Relationship Mapping Support)
(Example)
Line 370: Line 370:
 
<source lang="xml">
 
<source lang="xml">
 
<root>
 
<root>
     <employee-data id=100>
+
     <employee-data id="100">
 
         <address emp-id="100" type="HOME" />
 
         <address emp-id="100" type="HOME" />
 
     </employee-data>
 
     </employee-data>

Revision as of 13:53, 19 August 2010

Phase 3 - MOXy Equivalents of Relevant JPA Annotations

This phase of development involves providing additional MOXy annotations and XML metadata support equivalent to that of any relevant JPA annotations.

Annotations/XML Metadata

The following MOXy annotations/XML metadata will be targeted in this phase:

JPA Annotation MOXy Annotation XML Metadata Tag Package Type Field Method
DiscriminatorColumn XmlDiscriminatorNode xml-discriminator-node X
DiscriminatorValue XmlDiscriminatorValue xml-discriminator-value X
JoinColumn XmlJoinNode xml-join-node X X
JoinColumns XmlJoinNodes xml-join-nodes X X
N/A XmlAfterUnmarshal xml-after-unmarshal
N/A XmlBeforeUnmarshal xml-before-unmarshal
N/A XmlAfterMarshal xml-after-marshal
N/A XmlBeforeMarshal xml-before-marshal

Inheritance Support

XmlDiscriminatorNode

Purpose

Provide a means to set the class indicator field name when using inheritance.

Java Metadata

package org.eclipse.persistence.oxm.annotations;
 
@Target({TYPE}) 
@Retention(RUNTIME)
public @interface XmlDiscriminatorNode {
    String value();
}

XML Metadata

xml-discriminator-node

The xml-discriminator-node metadata tag will be used to set the class indicator field name when using inheritance. The value will be in the form of an XPath to an attribute, i.e. @xsi:type.

eclipselink-oxm.xml snippet

<java-type name="org.example.Vehicle" xml-discriminator-node="@vtype">

XmlDiscriminatorValue

Purpose

Provide a means to set a class indicator when using inheritance.

Java Metadata

package org.eclipse.persistence.oxm.annotations;
 
@Target({TYPE}) 
@Retention(RUNTIME)
public @interface XmlDiscriminatorValue {
    String value();
}

XML Metadata

xml-discriminator-value

The xml-discriminator-value metadata tag will be used to set a class indicator when using inheritance.

eclipselink-oxm.xml snippet

<java-type name="org.example.Car" xml-discriminator-value="car">

XML Schema

Following is the proposed XSD change necessary to provide support for inheritance:

<xs:element name="java-type">
    <xs:complexType>
        <xs:all>
            <xs:element ref="xml-type" minOccurs="0"/>
            <xs:element ref="xml-root-element" minOccurs="0"/>
            <xs:element ref="xml-see-also" minOccurs="0"/>
            <xs:element ref="xml-java-type-adapter" minOccurs="0"/>
            <xs:element ref="xml-class-extractor" minOccurs="0"/>
            <xs:element ref="xml-properties" minOccurs="0" />
            <xs:element name="java-attributes" minOccurs="0">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element ref="java-attribute" minOccurs="0" maxOccurs="unbounded" />
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:all>
        <xs:attribute name="name" type="xs:string" />
        <xs:attribute name="xml-accessor-order" type="xml-access-order" default="UNDEFINED" />
        <xs:attribute name="xml-accessor-type" type="xml-access-type" default="PUBLIC_MEMBER" />
        <xs:attribute name="xml-customizer" type="xs:string" />
        <xs:attribute name="xml-discriminator-node" type="xs:string" />
        <xs:attribute name="xml-discriminator-value" type="xs:string" />
        <xs:attribute name="xml-inline-binary-data" type="xs:boolean" default="false" />
        <xs:attribute name="xml-transient" type="xs:boolean" default="false" />
    </xs:complexType>
</xs:element>

Example

The following example will demonstrate how inheritance can be configured.

Using the xml-discriminator-node and xml-discriminator-value EclipseLink XML metadata tags to set the class indicator field name and class indicator(s) can be accomplished as follows:

<java-types>
    <java-type name="org.example.Vehicle" xml-discriminator-node="@vtype" xml-discriminator-value="vehicle">
        <xml-root-element name="vehicle-data" />
        <java-attributes>
            <xml-element java-attribute="topSpeed" name="top-speed" />
        </java-attributes>
    </java-type>
    <java-type name="org.example.Car" xml-discriminator-value="car">
        <xml-root-element name="car-data" /> 
        <java-attributes>
            <xml-element java-attribute="numberOfDoors" name="number-of-doors" />
            <xml-element java-attribute="milesPerGallon" name="miles-per-gallon" />
        </java-attributes>
    </java-type>
</java-types>

Setting the class indicator field name and class indicator(s) via Annotations would be accomplished as follows:

org.example.Vehicle.java

package org.example;
 
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorNode;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
 
@XmlRootElement("vehicle-data")
@XmlDiscriminatorNode("@vtype")
@XmlDiscriminatorValue("vehicle")
class Vehicle {
    public String model;
    public String manufacturer;
    @XmlElement(name="top-speed")
    public int topSpeed;
}

org.example.Car.java

package org.example;
 
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
 
@XmlRootElement("car-data")
@XmlDiscriminatorValue("car")
class Car {
    @XmlElement(name="number-of-doors")
    public int numberOfDoors;
    @XmlElement(name="miles-per-gallon")
    public int milesPerGallon;
}

Sample XML Instance Document

<vehicle-data vtype="car">
    <model>Mustang GT</model>
    <manufacturer>Ford</manufacturer>
    <top-speed>354</top-speed>
    <number-of-doors>2</number-of-doors>
    <miles-per-gallon>26</miles-per-gallon>
</vehicle-data>

Relationship Mapping Support

We currently support relationship mappings through @ID/@IDREF annotations, and xml-id/xml-idref metadata tags. There are a number of limitations when using these:

  • ID property must be of type String
  • Target class of an IDREF must have an ID property
  • Since a given class can have at most one ID property, there is no way to configure composite keys

Use of XmlJoinNode(s) will allow one or more properties in the target class to be used as the key for a relationship mapping.

XmlJoinNodes

Purpose

XmlJoinNodes is used to group one or more XmlJoinNode entries. Please see XmlJoinNode below for examples of use.

Java Metadata

package org.eclipse.persistence.oxm.annotations;
 
@Target({METHOD, FIELD}) 
@Retention(RUNTIME)
public @interface XmlJoinNodes {
    XmlJoinNode[] value();
}

XML Metadata

xml-join-nodes

xml-join-nodes will be used to group one or more xml-join-node entries. Please see xml-join-node below for additional information and examples of use.

XmlJoinNode

Purpose

XmlJoinNode identifies a key in the target object. For composite keys, XmlJoinNodes can be used.

Java Metadata

package org.eclipse.persistence.oxm.annotations;
 
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface XmlJoinNode {
    String name() default "";
    String referencedNodeName() default "";
 
    // are the following relevant?
    boolean unique() default false;
    boolean nullable() default true;
    boolean insertable() default true;
    boolean updatable() default true;
    String columnDefinition() default "";
    String table() default "";
}

XML Metadata

xml-join-node eclipselink-oxm.xml snippet

<xml-element java-attribute="address">
    <xml-join-nodes>
        <xml-join-node name="address/@emp-id" referencedNodeName="empId" />
        <xml-join-node name="address/@type" referencedNodeName="type" />
    </xml-join-nodes>
</xml-element>

XML Schema

Following is the proposed XSD change necessary to provide additional relationship mapping support:

<xs:element name="xml-join-nodes" type="xml-join-nodes" />
<xs:complexType name="xml-join-nodes">
    <xs:sequence>
        <xs:element name="xml-join-node" minOccurs="0" maxOccurs="unbounded" >
            <xs:complexType>
                <xs:attribute name="name" type="xs:string" use="required" />
                <xs:attribute name="referencedNodeName" type="xs:string" use="required" />
            </xs:complexType>
        </xs:element>
    </xs:sequence>
</xs:complexType>

Example

The following example will demonstrate how a relationship mapping with composite keys can be configured.

Using the xml-join-nodes and xml-join-node EclipseLink XML metadata tags to configure a relationship mapping can be accomplished as follows:

<java-types>
    <java-type name="org.example.Employee">
        <xml-root-element name="employee-data" />
        <java-attributes>
            <xml-attribute java-attribute="id" />
            <xml-element java-attribute="address">
                <xml-join-nodes>
                    <xml-join-node name="address/@emp-id" referencedNodeName="empId" />
                    <xml-join-node name="address/@type" referencedNodeName="type" />
                </xml-join-nodes>
            </xml-element>
        </java-attributes>
    </java-type>
    <java-type name="org.example.Address">
        <xml-root-element name="address-data" /> 
    </java-type>
</java-types>

Setting up a relationship mapping via Annotations would be accomplished as follows:

org.example.Employee.java

package org.example;
 
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
 
@XmlRootElement("employee-data")
class Employee {
    @XmlAttribute
    public String id;
 
    @XmlJoinNodes({
        @XmlJoinNode(name="address/@emp-id" referencedNodeName="empId"),
        @XmlJoinNode(name="address/@type" referencedNodeName="type")
    })
    public Address address;
}

org.example.Address.java

package org.example;
 
import javax.xml.bind.annotation.XmlRootElement;
 
@XmlRootElement("address-data")
class Address {
    public String empId;
    public String type;
    public String street;
    public String city;
    public String postal;
}

Sample XML Instance Document

<root>
    <employee-data id="100">
        <address emp-id="100" type="HOME" />
    </employee-data>
    <address-data>
        <empId>100</empId>
        <type>HOME</type>
        <street>99 Some St.</street>
        <city>Kanata</city>
        <postal>K0A3m0</postal>
    </address-data>
    <address-data>
        <empId>100</empId>
        <type>WORK</type>
        <street>45 O'Connor St., Suite 400</street>
        <city>Ottawa</city>
        <postal>K1P1A4</postal>
    </address-data>
    <address-data>
        <empId>200</empId>
        <type>HOME</type>
        <street>1 Anystreet Rd.</street>
        <city>Ottawa</city>
        <postal>K4P1A2</postal>
    </address-data>
</root>

Testing

This section identifies the test package(s) for each feature outlined on this page.

XML Metadata

XML Metadata Package
xml-discriminator-node org.eclipse.persistence.testing.jaxb.externalizedmetadata.inheritance
xml-discriminator-value org.eclipse.persistence.testing.jaxb.externalizedmetadata.inheritance

Annotations

Annotation Package

Open Issues

This section lists open issues.

Issue# Description/Notes
1

Decisions

This section lists decisions made. These are intended to document the resolution of open issues or constraints added to the project that are important.

Decision# Description/Notes Decision
1

Back to the top