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/REST/GettingStarted/XmlBinding"

(Next Steps)
(Customer Entity)
 
Line 44: Line 44:
  
 
     @OneToMany(mappedBy="customer", cascade={CascadeType.ALL})
 
     @OneToMany(mappedBy="customer", cascade={CascadeType.ALL})
     private Set<phonenumber> phoneNumbers;
+
     private Set<PhoneNumber> phoneNumbers;
  
 
     public long getId() {
 
     public long getId() {

Latest revision as of 18:02, 6 October 2010

Overview

Java Architecture for XML Binding (JAXB) is the Java EE standard for mapping POJOs to XML. In this example we will use JAXB to apply an XML representation to the JPA entities we created in part 2. Since we are mapping JPA entities to XML we will use the MOXy JAXB implementation and leverage some of its extensions.

Some developers will maintain separate JPA and JAXB models, and perform a copy step to move data between them. This can be quite a painful and error prone process. Luckily MOXy has a number of extensions that make this unnessary.

jaxb.properties

To use the MOXy implementation of JAXB you need to add a file called jaxb.properties in with your model classes with the following entry:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

Customer Entity

JAX-RS requires that we annotate the root object with the JAXB annotation @XmlRootElement. Since Customer will be our root object we will add the annotation.

package org.example;
 
import java.io.Serializable;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlRootElement;
 
import java.util.Set;
 
@Entity
@XmlRootElement
public class Customer implements Serializable {
    private static final long serialVersionUID = 1L;
 
    @Id
    private long id;
 
    @Column(name="FIRST_NAME")
    private String firstName;
 
    @Column(name="LAST_NAME")
    private String lastName;
 
    @OneToOne(mappedBy="customer", cascade={CascadeType.ALL})
    private Address address;
 
    @OneToMany(mappedBy="customer", cascade={CascadeType.ALL})
    private Set<PhoneNumber> phoneNumbers;
 
    public long getId() {
        return this.id;
    }
 
    public void setId(long id) {
        this.id = id;
    }
 
    public String getFirstName() {
        return this.firstName;
    }
 
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
 
    public String getLastName() {
        return this.lastName;
    }
 
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
 
    public Address getAddress() {
        return this.address;
    }
 
    public void setAddress(Address address) {
        this.address = address;
    }
 
    public Set<phonenumber> getPhoneNumbers() {
        return this.phoneNumbers;
    }
 
    public void setPhoneNumbers(Set<phonenumber> phoneNumbers) {
        this.phoneNumbers = phoneNumbers;
    }
 
}

Address Entity

The Address entity has a property "customer" that references back to the owning Customer entity. In other words there is a bidirectional relationship. We will use MOXy's @XmlInverseReference annotation to map this relationship. This issue is discussed deeper in the following post JPA Entities to XML - Bidirectional Relationships.

Since relationships in JPA may be "lazy" (not triggered until the property is accessed through the "get" method), we will annotate the property (get/set method), instead of the field (instance variable).

package org.example;
 
import java.io.Serializable;
import javax.persistence.*;
 
import org.eclipse.persistence.oxm.annotations.XmlInverseReference;
 
@Entity
public class Address implements Serializable {
    private static final long serialVersionUID = 1L;
 
    @Id
    private long id;
 
    private String city;
 
    private String street;
 
    @OneToOne
    @PrimaryKeyJoinColumn
    private Customer customer;
 
    public long getId() {
        return this.id;
    }
 
    public void setId(long id) {
        this.id = id;
    }
 
    public String getCity() {
        return this.city;
    }
 
    public void setCity(String city) {
        this.city = city;
    }
 
    public String getStreet() {
        return this.street;
    }
 
    public void setStreet(String street) {
        this.street = street;
    }
 
    @XmlInverseReference(mappedBy="address")
    public Customer getCustomer() {
        return customer;
    }
 
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
 
}

PhoneNumber Entity

We will also need to address the bidirectional relationship in the PhoneNumber entity.

package org.example;
 
import java.io.Serializable;
import javax.persistence.*;
 
import org.eclipse.persistence.oxm.annotations.XmlInverseReference;
 
@Entity
@Table(name="PHONE_NUMBER")
public class PhoneNumber implements Serializable {
    private static final long serialVersionUID = 1L;
 
    @Id 
    private long id;
 
    private String num;
 
    private String type;
 
    @ManyToOne
    @JoinColumn(name="ID_CUSTOMER")
    private Customer customer;
 
    public long getId() {
        return this.id;
    }
 
    public void setId(long id) {
        this.id = id;
    }
 
    public String getNum() {
        return this.num;
    }
 
    public void setNum(String num) {
        this.num = num;
    }
 
    public String getType() {
        return this.type;
    }
 
    public void setType(String type) {
        this.type = type;
    }
 
    @XmlInverseReference(mappedBy="phoneNumbers")
    public Customer getCustomer() {
        return this.customer;
    }
 
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
 
}

Server Setup

GlassFish v3.0.1 does not include the MOXy bundle (org.eclipse.persistence.core.jar). It should be added to <glassfish_home>/glashfish/modules. The necessary binaries from here:

Next Steps

In part 4 we will examine how to use the Java API for RESTful Web Services (JAX-RS) to create a RESTful service from an EJB session bean that can perform CRUD operations on our Customer model via XML.

Back to the top