Java Persistence Architecture (JPA) is the Java EE standard for mapping POJOs to a relational database. In this example we will use JPA to interact with our database data we set up in part 1.
- Part 1 - The Database
- Part 2 - Mapping the Database to JPA Entities
- Part 3 - Mapping JPA entities to XML (using JAXB)
- Part 4 - The RESTful Service
- Part 5 - The Client
JPA Entities
The following JPA entities can be created by hand, or the Eclipse Dali project can be used (http://www.eclipse.org/webtools/dali/). Dali has a useful feature where JPA entities can be generated from database tables.
Customer Entity
We want the customer, address, and phone number data to be treated as a unit. When a customer is added/removed we want the corresponding address and phone numbers to be added/removed. To accomplish this we will specify CascadeType.ALL on the address and phoneNumber relationships.
In addition to the database mappings, I've added a named query to the Customer entity. This query will give us all customers from a particular city.
package org.example; import java.io.Serializable; import javax.persistence.*; import java.util.Set; @Entity @NamedQuery(name = "findCustomersByCity", query = "SELECT c " + "FROM Customer c " + "WHERE c.address.city = :city") 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
package org.example; import java.io.Serializable; import javax.persistence.*; @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; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } }
PhoneNumber Entity
package org.example; import java.io.Serializable; import javax.persistence.*; @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; } public Customer getCustomer() { return this.customer; } public void setCustomer(Customer customer) { this.customer = customer; } }
META-INF/persistence.xml
For this example I will use the EclipseLink JPA implementation. If you are using another JPA implementation the configuration willl vary slightly.
<?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="CustomerService" transaction-type="JTA"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <jta-data-source>CustomerService</jta-data-source> <class>org.example.Customer</class> <class>org.example.Address</class> <class>org.example.PhoneNumber</class> <properties> <property name="eclipselink.target-database" value="Oracle" /> <property name="eclipselink.logging.level" value="FINEST" /> <property name="eclipselink.logging.level.ejb_or_metadata" value="WARNING" /> <property name="eclipselink.logging.timestamp" value="false"/> <property name="eclipselink.logging.thread" value="false"/> <property name="eclipselink.logging.session" value="false"/> <property name="eclipselink.logging.exceptions" value="false"/> <property name="eclipselink.target-server" value="SunAS9"/> </properties> </persistence-unit> </persistence>
Packaging/Deployment
Ultimately we will package all the META-INF/pesistence.xml and our JPA entities in a JAR file. We will hold off actually creating the JAR until we apply the XML representation using JAXB in part 3.
Next Steps
In the next post we will examine how to use the Java Architecture for XML Binding (JAXB) to apply an XML representation on the JPA entities (POJOs).
- Part 1 - The Database
- Part 2 - Mapping the Database to JPA Entities
- Part 3 - Mapping JPA entities to XML (using JAXB)
- Part 4 - The RESTful Service
- Part 5 - The Client
Further Reading
If you enjoyed this post you may also be interested in:
- RESTful Services
- MOXy's XML Metadata in a JAX-RS Service
- MOXy as Your JAX-RS JSON Provider - Server Side
- MOXy as Your JAX-RS JSON Provider - Client Side
- Application Server Integration
hi Blaise,
ReplyDeletecould you please show me an example how to marshal Composite PK inline?
For example:
public class FreeUnit implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
protected FreeUnitPK freeUnitPK;
}
I would like to have the fields of PK inline in XML of FreeUnit.
regards,
Tinku
Hi Tinku,
ReplyDeleteBelow is a link on how to handle composite primary keys with EclipseLink JAXB (MOXy):
- Mapping Composite Key Relationships
The above strategy will also work when using @EmbeddedId.
-Blaise