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/Mapping JPA Entities to XML/Lazily Loaded Fields/Properties"
m (→Source Object) |
m |
||
Line 7: | Line 7: | ||
− | This example demonstrates how to derive an XML representation from a set of JPA entities using JAXB when a JPA entity has an embedded ID class. | + | This example demonstrates how to derive an XML representation from a set of JPA entities using JAXB, when a JPA entity has an embedded ID class. |
− | + | = JPA Entities == | |
+ | The following JPA entities are used in this example: | ||
<source lang="java"> | <source lang="java"> | ||
Line 52: | Line 53: | ||
== JAXB Bindings == | == JAXB Bindings == | ||
− | + | Here, the XML accessor type type is set to '''FIELD''' for all model classes. This can be set as a package level JAXB annotation. | |
− | + | ||
<source lang="java"> | <source lang="java"> | ||
Line 64: | Line 64: | ||
=== Target Object === | === Target Object === | ||
− | + | This entity uses the '''@XmLCustomizer''' EclipseLink extension to extend the JAXB specification. Because the relationship is bidirectional, we'll also use the '''@XmlInverseReference''' EclipseLink extension. | |
− | + | ||
<source lang="java"> | <source lang="java"> | ||
Line 83: | Line 82: | ||
</source> | </source> | ||
− | + | To have the '''EmployeeId''' class be embedded in the complex type corresponding to the '''Employee''' class, change the XPath on the mapping for the '''id''' property to be self or '''.'''. | |
− | Then | + | Then specify the XPath to the XML nodes which represent the ID. |
<source lang="java"> | <source lang="java"> | ||
Line 107: | Line 106: | ||
=== Source Object === | === Source Object === | ||
− | If the target object had a single ID then we would use @XmlIDREF. | + | If the target object had a single ID then we would use '''@XmlIDREF'''. However, 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"> | <source lang="java"> | ||
Line 125: | Line 124: | ||
</source> | </source> | ||
− | An XMLObjectReferenceMapping will be created. The mapping will include multiple key mappings. | + | An '''XMLObjectReferenceMapping''' will be created. The mapping will include multiple key mappings. |
<source lang="java"> | <source lang="java"> |
Revision as of 10:00, 23 May 2011
EclipseLink MOXy
EclipseLink | |
Website | |
Download | |
Community | |
Mailing List • Forums • IRC • mattermost | |
Issues | |
Open • Help Wanted • Bug Day | |
Contribute | |
Browse Source |
This example demonstrates how to derive an XML representation from a set of JPA entities using JAXB, when a JPA entity has an embedded ID class.
JPA Entities =
The following JPA entities are used in this 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 { @EmbeddedId private EmployeeId id; @OneToMany(mappedBy="contact") private List<PhoneNumber> contactNumber; }
@Embeddable public class EmployeeId { @Column(name="E_ID") private BigDecimal eId; private String country; }
JAXB Bindings
Here, the XML accessor type type is set to FIELD for all model classes. This can be set as a package level JAXB annotation.
@XmlAccessorType(XmlAccessType.FIELD) package com.example.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType;
Target Object
This entity uses the @XmLCustomizer EclipseLink extension to extend the JAXB specification. Because the relationship is bidirectional, we'll also use the @XmlInverseReference EclipseLink extension.
@Entity @IdClass(EmployeeId.class) @XmlCustomizer(EmployeeCustomizer.class) public class Employee { @EmbeddedId private EmployeeId id; @OneToMany(mappedBy="contact") @XmlInverseReference(mappedBy="contact") private List<PhoneNumber> contactNumber; }
To have the EmployeeId class be embedded 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.
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 Object
If the target object had a single ID then we would use @XmlIDREF. However, 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.
@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; }
An XMLObjectReferenceMapping will be created. The mapping will include 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); } }