|
|
(10 intermediate revisions by 2 users not shown) |
Line 1: |
Line 1: |
− | {{EclipseLink_UserGuide
| + | See http://www.eclipse.org/eclipselink/documentation/2.4/moxy/shared_reference_relationships004.htm |
− | |info=y
| + | |
− | |api=y
| + | |
− | |apis= * [http://www.eclipse.org/eclipselink/api/latest/javax/xml/bind/annotation/XmlAccessType.html javax.xml.bind.annotation.XmlAccessType]
| + | |
− | * [http://www.eclipse.org/eclipselink/api/latest/javax/xml/bind/annotation/XmlCustomizer.html javax.xml.bind.annotation.XmlCustomizer]
| + | |
− | * [http://www.eclipse.org/eclipselink/api/latest/javax/xml/bind/annotation/XmlInverseReference.html javax.xml.bind.annotation.XmlInverseReference]
| + | |
− | |eclipselink=y
| + | |
− | |eclipselinktype=MOXy
| + | |
− | }}
| + | |
− | | + | |
− | = Using Composite (Compound) Primary Keys =
| + | |
− | With JAXB, you can generate XML from a set of JPA entities with composite (compound) primary keys.
| + | |
− | | + | |
− | For example, consider the following example:
| + | |
− | | + | |
− | <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;
| + | |
− | | + | |
− | }
| + | |
− | | + | |
− | @Entity
| + | |
− | @IdClass(EmployeeId.class)
| + | |
− | public class Employee {
| + | |
− | | + | |
− | @Id
| + | |
− | @Column(name="E_ID")
| + | |
− | private BigDecimal eId;
| + | |
− | | + | |
− | @Id
| + | |
− | private String country;
| + | |
− | | + | |
− | @OneToMany(mappedBy="contact")
| + | |
− | private List<PhoneNumber> contactNumber;
| + | |
− | | + | |
− | }
| + | |
− | | + | |
− | public class EmployeeId {
| + | |
− | | + | |
− | private BigDecimal eId;
| + | |
− | private String country;
| + | |
− | | + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | In this example, set the '''XmlAccessType''' to '''FIELD''' for each model class. You can configure this 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>
| + | |
− | | + | |
− | === Target Object ===
| + | |
− | You can use the EclispeLink '''@XmlCustomizer''' for configuration options beyond the JAXB specification. Because the relationship is bidirectional, you must use the '''@XmlInverseReference''' extension, as shown here:
| + | |
− | | + | |
− | <source lang="java">
| + | |
− | @Entity
| + | |
− | @IdClass(EmployeeId.class)
| + | |
− | @XmlCustomizer(EmployeeCustomizer.class)
| + | |
− | public class Employee {
| + | |
− | | + | |
− | @Id
| + | |
− | @Column(name="E_ID")
| + | |
− | private BigDecimal eId;
| + | |
− | | + | |
− | @Id
| + | |
− | private String country;
| + | |
− | | + | |
− | @OneToMany(mappedBy="contact")
| + | |
− | @XmlInverseReference(mappedBy="contact")
| + | |
− | private List<PhoneNumber> contactNumber;
| + | |
− | | + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | You must also 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;
| + | |
− | | + | |
− | public class EmployeeCustomizer implements DescriptorCustomizer {
| + | |
− | | + | |
− | public void customize(ClassDescriptor descriptor) throws Exception {
| + | |
− | descriptor.addPrimaryKeyFieldName("eId/text()");
| + | |
− | descriptor.addPrimaryKeyFieldName("country/text()");
| + | |
− | }
| + | |
− | | + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | === Source Object ===
| + | |
− | | + | |
− | If the target object had a single ID then we would use '''[[EclipseLink/UserGuide/MOXy/Relationships/Shared_Reference/Keys_and_Foreign_Keys/Single_Key|@XmlIDREF]]'''. Because the target object has a ''compound key'', use the '''@XmlTransient''' annotation.
| + | |
− | | + | |
− | Use the EclipseLink '''@XmlCustomizer''' extension to create the mapping as shown here.
| + | |
− | | + | |
− | <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>
| + | |
− | | + | |
− | EclipseLink creates the '''XMLObjectReferenceMapping'''. This mapping includes 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>
| + | |
− | | + | |
− | | + | |
− | | + | |
− | {{EclipseLink_MOXy
| + | |
− | |previous=[[EclipseLink/UserGuide/MOXy/Relationships/Shared Reference/Keys and Foreign Keys/Single Key|Single Key]]
| + | |
− | |up =[[EclipseLink/UserGuide/MOXy/Relationships/Shared Reference/Keys and Foreign Keys|Keys and Foreign Keys]]
| + | |
− | |next =[[EclipseLink/UserGuide/MOXy/Relationships/Shared Reference/Keys and Foreign Keys/Embedded Key Class|Embedded Key Class]]
| + | |
− | |version=2.2.0 DRAFT
| + | |
− | }}
| + | |