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/Mapping JPA Entities to XML/Embedded Key Class"

(New page: {{EclipseLink_UserGuide |info=y }} = Embedded Key Class = With JAXB, you can derive an XML representation from a set of JPA entities, when a JPA entity has an embedded ID class. In the ...)
 
m (Replacing page with ''''Warning This page is obsolete. Please see ''[http://www.eclipse.org/eclipselink/documentation/ Developing JAXB Applications Using EclipseLink M...')
 
Line 1: Line 1:
{{EclipseLink_UserGuide
+
'''[[Image:Elug_draft_icon.png|Warning]] This page is obsolete. Please see ''[http://www.eclipse.org/eclipselink/documentation/ Developing JAXB Applications Using EclipseLink MOXy]'' for current information.'''
|info=y
+
}}
+
= Embedded Key Class =
+
With JAXB, you can derive an XML representation from a set of JPA entities, when a JPA entity has an embedded ID class.
+
 
+
 
+
In the following code, the '''EmployeeId''' is the embedded ID of the '''Employee''' class:
+
 
+
<source lang="java">
+
@Entity
+
public class PhoneNumber {
+
 
+
    @ManyToOne
+
    @JoinColumns({
+
        @JoinColumn(name="E_ID", referencedColumnName = "E_ID"),
+
        @JoinColumn(name="E_COUNTRY", referencedColumnName = "COUNTRY")
+
    })
+
    private Employee contact;
+
 
+
}
+
</source>
+
 
+
<source lang="java">
+
@Entity
+
@IdClass(EmployeeId.class)
+
public class Employee {
+
 
+
    @EmbeddedId
+
    private EmployeeId id;
+
 
+
    @OneToMany(mappedBy="contact")
+
    private List<PhoneNumber> contactNumber;
+
 
+
}
+
</source>
+
 
+
<source lang="java">
+
@Embeddable
+
public class EmployeeId {
+
 
+
    @Column(name="E_ID")
+
    private BigDecimal eId;
+
 
+
    private String country;
+
 
+
}
+
</source>
+
 
+
For the JAXB bindings, the XML acessor type will be set to '''FIELD''' for all the model classes.  This can be set as a package level JAXB annotation, as shown here:
+
 
+
<source lang="java">
+
@XmlAccessorType(XmlAccessType.FIELD)
+
package com.example.model;
+
 
+
import javax.xml.bind.annotation.XmlAccessType;
+
import javax.xml.bind.annotation.XmlAccessorType;
+
</source>
+
 
+
 
+
The following code uses the EclipseLink extension '''@XmlCustomizer''' which extends the JAXB specification. Because the '''contact''' attribute is a bidirectional relationship, it includes the EclipseLink extension '''@XmlInverseReference'''.
+
 
+
<source lang="java">
+
@Entity
+
@IdClass(EmployeeId.class)
+
@XmlCustomizer(EmployeeCustomizer.class)
+
public class Employee {
+
 
+
    @EmbeddedId
+
    private EmployeeId id;
+
 
+
    @OneToMany(mappedBy="contact")
+
    @XmlInverseReference(mappedBy="contact")
+
    private List<PhoneNumber> contactNumber;
+
 
+
}
+
</source>
+
 
+
 
+
To embed the content of the '''EmployeeId''' class in the complex type corresponding to the '''Employee''' class, change the XPath on the mapping for the '''id'''  property to be self or '''.'''. Then specify the XPath to the XML nodes which represent the ID.
+
 
+
<source lang="java">
+
import org.eclipse.persistence.config.DescriptorCustomizer;
+
import org.eclipse.persistence.descriptors.ClassDescriptor;
+
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
+
 
+
public class EmployeeCustomizer implements DescriptorCustomizer {
+
 
+
    public void customize(ClassDescriptor descriptor) throws Exception {
+
        XMLCompositeObjectMapping idMapping =
+
            (XMLCompositeObjectMapping) descriptor.getMappingForAttributeName("id");
+
        idMapping.setXPath(".");
+
 
+
        descriptor.addPrimaryKeyFieldName("eId/text()");
+
        descriptor.addPrimaryKeyFieldName("country/text()");
+
    }
+
 
+
}</source>
+
 
+
 
+
 
+
If the target object had a single ID then we would use '''@XmlIDREF'''. Since the target object has a compound key, we will mark the field @XmlTransient, and use the EclipseLink extension '''@XmlCustomizer''' to set up the mapping.
+
 
+
<source lang="java">
+
@Entity
+
@XmlCustomizer(PhoneNumberCustomizer.class)
+
public class PhoneNumber {
+
 
+
    @ManyToOne
+
    @JoinColumns({
+
        @JoinColumn(name="E_ID", referencedColumnName = "E_ID"),
+
        @JoinColumn(name="E_COUNTRY", referencedColumnName = "COUNTRY")
+
    })
+
    @XmlTransient
+
    private Employee contact;
+
 
+
}
+
</source>
+
 
+
An XMLObjectReferenceMapping will be created.  The mapping will include multiple key mappings.
+
 
+
<source lang="java">
+
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);
+
    }
+
 
+
}
+
</source>
+

Latest revision as of 13:17, 30 January 2013

Warning This page is obsolete. Please see Developing JAXB Applications Using EclipseLink MOXy for current information.

Copyright © Eclipse Foundation, Inc. All Rights Reserved.