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/Examples/MOXy/JPA/CompoundPrimaryKeys"

< EclipseLink‎ | Examples‎ | MOXy‎ | JPA
(JPA Entities)
(Target Object)
Line 61: Line 61:
 
=== Target Object ===
 
=== Target Object ===
  
As we require support beyond the JAXB spec, we will make use the EclipseLink extension @XmlCustomizer.  Also since the relationship is bidirectional, we will use the EclipseLink extension @XmlInverseReference.
+
As we require support beyond the JAXB spec, we will make use of the EclipseLink extensions @XmlKey and @XmlJoinNodes.  Also since the relationship is bidirectional, we will use the EclipseLink extension @XmlInverseReference.
  
 
<source lang="java">
 
<source lang="java">
Line 71: Line 71:
 
     @Id
 
     @Id
 
     @Column(name="E_ID")
 
     @Column(name="E_ID")
 +
    @XmlID
 
     private BigDecimal eId;
 
     private BigDecimal eId;
  
 
     @Id
 
     @Id
 +
    @XmlKey
 
     private String country;
 
     private String country;
  
Line 79: Line 81:
 
     @XmlInverseReference(mappedBy="contact")
 
     @XmlInverseReference(mappedBy="contact")
 
     private List<PhoneNumber> contactNumber;
 
     private List<PhoneNumber> contactNumber;
 
}
 
</source>
 
 
Then we must 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()");
 
    }
 
  
 
}
 
}

Revision as of 16:29, 16 March 2011

Overview

This example demonstrates how to derive an XML representation from a set of JPA entities using JAXB when a JPA entity has compound primary keys.

JPA Entities

@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;
 
}

JAXB Bindings

For this example the XML acessor type will be set to FIELD for all the 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

As we require support beyond the JAXB spec, we will make use of the EclipseLink extensions @XmlKey and @XmlJoinNodes. Also since the relationship is bidirectional, we will use the EclipseLink extension @XmlInverseReference.

@Entity
@IdClass(EmployeeId.class)
@XmlCustomizer(EmployeeCustomizer.class)
public class Employee {
 
    @Id
    @Column(name="E_ID")
    @XmlID
    private BigDecimal eId;
 
    @Id
    @XmlKey
    private String country;
 
    @OneToMany(mappedBy="contact")
    @XmlInverseReference(mappedBy="contact")
    private List<PhoneNumber> contactNumber;
 
}

Source Object

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.

@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);
    }
 
}

Copyright © Eclipse Foundation, Inc. All Rights Reserved.