Java EE developers are increasingly required to embrace thin-server-architecture client application development while leveraging their existing components. On the surface, this appears to simply mean using JAX-RS to expose RESTful services. But the real challenges are often misunderstood and underestimated. EclipseLink has solved a large part of this problem through its new JPA-RS feature which integrates JAX-RS, JAXB and JPA to allow developers to expose their persistent entities over REST with support for all lifecycle operations and query execution. In building JPA-RS, EclipseLink faced and overcame many of the challenges developers face when realizing a REST resource model, addressing HATEOS, and the infrastructure for JSON and XML binding.
17. EclipseLink MOXy
•
•
•
JAXB for Java/XML binding—covert Java to/from XML
Java/JSON binding—convert Java to/from JSON
Currently no Java/JSON binding standard
• Java API for JSON Processing (JSR 535) is parsing, not binding
• EclipseLink interprets JAXB XML bindings for JSON
• Content-type selectable by setting property on
Marshaller/Unmarshaller
#DV13 #JPARS
@shaunMsmith
20. Bidirectional Relationship
@Entity
public class Customer{
...
@OneToMany(mappedBy="owner")
private List<Phone> phones;
}
@Entity
public class Phone{
...
@ManyToOne
private Customer owner;
}
#DV13 #JPARS
@shaunMsmith
21. What about @XmlTransient?
@Entity
public class Customer{
...
@OneToMany(mappedBy=“owner")
private List<Phone> phones;
}
@Entity
public class Phone{
...
@ManyToOne
@XmlTransient
private Customer owner;
}
#DV13 #JPARS
@shaunMsmith
22. With @XmlTransient
Loses the relationship!
owner
Customer
phones
#DV13 #JPARS
Phone
<customer>
<phone-numbers>
<phone-number>
<id>1</id>
...
<type>mobile</type>
</phone-number>
</phone-numbers>
</customer>
Marshall
Marshall
X
Customer
Unmarshall
Unmarshall
Phone
phones
@shaunMsmith
23. EclipseLink XmlInverseReference
@Entity
public class Customer{
...
@OneToMany(mappedBy=“owner")
private List<Phone> phones;
}
@Entity
public class Phone{
...
@ManyToOne
@XmlInverseReference(mappedBy=“phones")
private Customer owner;
}
#DV13 #JPARS
@shaunMsmith
27. JAX-RS with JPA Example
public class InvoiceService {...
public Invoice read(int id) {
return null;
}
...
#DV13 #JPARS
@shaunMsmith
28. JAX-RS with JPA Example
@Stateless
public class InvoiceService {...
public Invoice read(int id) {
return entityManager.find(Invoice.class, id);
}
...
#DV13 #JPARS
@shaunMsmith
29. JAX-RS with JPA Example
@Path("/invoice")
@Stateless
public class InvoiceService {...
public Invoice read(int id) {
return entityManager.find(Invoice.class, id);
}
...
#DV13 #JPARS
http://[machine]:[port]/[web-context]/invoice
http://[machine]:[port]/[web-context]/invoice
@shaunMsmith
30. JAX-RS with JPA Example
@Path("/invoice")
@Stateless
public class InvoiceService {...
@Path("{id}”)
public Invoice read(@PathParam("id") int id) {
return entityManager.find(Invoice.class, id);
}
...
#DV13 #JPARS
http://[machine]:[port]/[web-context]/invoice/4
http://[machine]:[port]/[web-context]/invoice/4
@shaunMsmith
31. JAX-RS with JPA Example
@Path("/invoice")
@Stateless
public class InvoiceService {...
@GET
@Path("{id}”)
public Invoice read(int id) {
return entityManager.find(Invoice.class, id);
}
...
#DV13 #JPARS
GET http://[machine]:[port]/[web-context]/invoice/4
GET http://[machine]:[port]/[web-context]/invoice/4
@shaunMsmith
32. JAX-RS with JPA Example
@Path("/invoice")
@Stateless
public class InvoiceService {...
@Produces({"application/xml"})
@GET
@Path("{id}")
public Invoice read(@PathParam("id") int id) {
return entityManager.find(Invoice.class, id);
}
...
#DV13 #JPARS
GET http://[machine]:[port]/[web-context]/invoice/4
GET http://[machine]:[port]/[web-context]/invoice/4
@shaunMsmith
33. JAX-RS with JPA
GET http://.../invoice/4
GET http://.../invoice/4
http://.../invoice/4 mapped to
http://.../invoice/4 mapped to
JAX-RS
JAX-RS
beanGET http://.../invoice/4 mapped to method
beanGET http://.../invoice/4 mapped to method
Invoice Bean
GET
GET
GET
GET
GET
GET
GET
GET
Bean uses JPA
Bean uses JPA
Contract Bean
GET
GET
GET
GET
GET
GET
Payment Bean
GET
GET
GET
GET
GET
GET
...
Accounting PU
JPA
#DV13 #JPARS
@shaunMsmith
35. EclipseLink JPA-RS
•
Automatically provides REST operations for entities in
persistence unit (GET, PUT, POST, DELETE)
•
Automatic generation of XML and JSON bindings
• Leverages EclipseLink’s JAXB/JPA fidelity features to avoid lossy
transformations
•
Automatic publication of REST API metadata
#DV13 #JPARS
@shaunMsmith
36. EclipseLink JPA-RS
•
Supports invocation of named queries via HTTP
•
Server side caching—EclipseLink clustered cache
•
Automatic injection of links for entity relationships
• Default Resource Model generation
#DV13 #JPARS
@shaunMsmith
39. JPA-RS
GET http://.../persistence/Accounting/Invoice/4
GET http://.../persistence/Accounting/Invoice/4
JAX-RS http://.../persistence/Accounting/Invoice/4
JAX-RS http://.../persistence/Accounting/Invoice/4
JAX-RS
JAX-RS
mapped to JPA-RS service
mapped to JPA-RS service
Accounting
JPA-RS
JPA-RS maps URI
JPA-RS maps URI
http://.../persistence/Accounting/Invoice/4 to
http://.../persistence/Accounting/Invoice/4 to
Human Resources
Accounting PU and Invoice entity
Accounting PU and Invoice Benefits
entity
...
JPA
#DV13 #JPARS
@shaunMsmith
44. Summary
•
•
•
Java EE stack has (most of) what you need to build Thin Server
Architecture applications
You have to be aware of various impedance mismatches
EclipseLink JPA-RS
• Integrates JAX-RS / JAXB / JPA
• Eliminates JAX-RS boilerplate for data access
• Simplifies Java EE Thin Server Architecture applications
☛ www.eclipse.org/eclipselink
#DV13 #JPARS
@shaunMsmith
45. The preceding is intended to outline our general product
direction. It is intended for information purposes only, and may
not be incorporated into any contract. It is not a commitment to
deliver any material, code, or functionality, and should not be
relied upon in making purchasing decisions. The development,
release, and timing of any features or functionality described for
Oracle’s products remains at the sole discretion of Oracle.
#DV13 #JPARS
@shaunMsmith