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.
Difference between revisions of "EclipseLink/UserGuide/MOXy/Relationships/Shared Reference/Keys and Foreign Keys/Composite Key"
m |
m |
||
Line 2: | Line 2: | ||
|info=y | |info=y | ||
|api=y | |api=y | ||
− | |apis= | + | |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 | |eclipselink=y | ||
|eclipselinktype=MOXy | |eclipselinktype=MOXy | ||
Line 50: | Line 52: | ||
</source> | </source> | ||
− | In this example, set the '''XmlAccessType''' to '''FIELD''' for each model class. You can | + | 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"> | <source lang="java"> |
Revision as of 14:39, 6 January 2011
EclipseLink MOXy
EclipseLink | |
Website | |
Download | |
Community | |
Mailing List • Forums • IRC • mattermost | |
Issues | |
Open • Help Wanted • Bug Day | |
Contribute | |
Browse Source |
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:
@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; }
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:
@XmlAccessorType(XmlAccessType.FIELD) package com.example.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType;
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:
@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; }
You must also specify the XPath to the XML nodes which represent the ID:
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 Object
If the target object had a single ID then we would use @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.
@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; }
EclipseLink creates the XMLObjectReferenceMapping. This mapping includes multiple key mappings.
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); } }