- Oracle 12c Database
- Eclipse Mars
- Coherence 12c 12.2.1
Here is the major steps for implementation
- Creating JPA Persistence Unit and Entities
- Create the Cache Configuration File for JPA
- Create a Java Client to Interact with Data Object
Step 1 Creating JPA Persistence Unit and Entities
The first step in implementing JPA is creating entities & persistent configuration. I am assuming that you have created the necessary JPA project & added the required libraries for creating the entities.
I am using Order, Order Entry & Product Information tables from the OE schema. The below is the corresponding java entities.
Orders.java
/**
* The persistent class for the ORDERS database table.
*
*/
@Entity
@Table(name="ORDERS")
@NamedQuery(name="Order.findAll", query="SELECT o FROM Order o")
public class Order implements Serializable, PortableObject {
private static final long serialVersionUID = 1L;
@Id
@Column(name="ORDER_ID")
private long orderId;
@Column(name="CUSTOMER_ID")
private long customerId;
//@Column(name="ORDER_DATE")
//private Timestamp orderDate;
@Column(name="ORDER_MODE")
private String orderMode;
@Column(name="ORDER_STATUS")
private Float orderStatus;
@Column(name="ORDER_TOTAL")
private Float orderTotal;
@Column(name="PROMOTION_ID")
private long promotionId;
@Column(name="SALES_REP_ID")
private long salesRepId;
//bi-directional many-to-one association to OrderItem
@OneToMany(mappedBy="order", fetch=FetchType.EAGER)
private List<OrderItem> orderItems;
public Order() {
}
public List<OrderItem> getOrderItems() {
return this.orderItems;
}
public void setOrderItems(List<OrderItem> orderItems) {
this.orderItems = orderItems;
}
public OrderItem addOrderItem(OrderItem orderItem) {
getOrderItems().add(orderItem);
orderItem.setOrder(this);
return orderItem;
}
public OrderItem removeOrderItem(OrderItem orderItem) {
getOrderItems().remove(orderItem);
orderItem.setOrder(null);
return orderItem;
}
@Override
public void readExternal(PofReader in) throws IOException {
this.orderId = in.readLong(0);
this.customerId = in.readLong(1);
this.orderMode = in.readString(2);
this.orderStatus = in.readFloat(3);
this.orderTotal = in.readFloat(4);
this.promotionId = in.readLong(5);
this.salesRepId = in.readLong(6);
this.orderItems = in.readCollection(7, this.orderItems);
//this.orderDate = in.readObject(8);
}
@Override
public void writeExternal(PofWriter out) throws IOException {
out.writeLong(0, this.orderId);
out.writeFloat(1, this.customerId);
out.writeString(2, this.orderMode);
out.writeFloat(3, this.orderStatus);
out.writeFloat(4, this.orderTotal);
out.writeLong(5, this.promotionId);
out.writeLong(6, this.salesRepId);
out.writeCollection(7, this.orderItems);
//out.writeObject(8, this.orderDate);
}
}
OrderItem.Java
@Entity
@Table(name="ORDER_ITEMS")
@NamedQuery(name="OrderItem.findAll", query="SELECT o FROM OrderItem o")
public class OrderItem implements Serializable, PortableObject {
private static final long serialVersionUID = 1L;
@EmbeddedId
private OrderItemPK id;
@Column(name="QUANTITY")
private long quantity;
@Column(name="UNIT_PRICE")
private long unitPrice;
//bi-directional many-to-one association to Order
@ManyToOne
@JoinColumn(name="ORDER_ID")
private Order order;
//bi-directional many-to-one association to ProductInformation
@ManyToOne
@JoinColumn(name="PRODUCT_ID")
private ProductInformation productInformation;
public OrderItem() {
}
public OrderItemPK getId() {
return this.id;
}
public Order getOrder() {
return this.order;
}
public void setOrder(Order order) {
this.order = order;
}
public ProductInformation getProductInformation() {
return this.productInformation;
}
public void setProductInformation(ProductInformation productInformation) {
this.productInformation = productInformation;
}
@Override
public void readExternal(PofReader in) throws IOException {
this.quantity = in.readLong(0);
this.unitPrice = in.readLong(1);
this.productInformation = in.readObject(2);
this.id = in.readObject(3);
this.order = in.readObject(4);
//this.order = in.readObject(4);
}
@Override
public String toString() {
return "OrderItem [id=" + id + ", quantity=" + quantity + ", unitPrice=" + unitPrice + ", order=" + order
+ ", productInformation=" + productInformation + "]";
}
@Override
public void writeExternal(PofWriter out) throws IOException {
out.writeLong(0, this.quantity);
out.writeLong(1, this.unitPrice);
out.writeObject(2, this.productInformation);
out.writeObject(3, this.id);
out.writeObject(4, this.order);
}
}
OrderItemPK.java
package entities;
import java.io.IOException;
import java.io.Serializable;
import javax.persistence.*;
import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;
/**
* The primary key class for the ORDER_ITEMS database table.
*
*/
@Embeddable
public class OrderItemPK implements Serializable, PortableObject {
@Override
public String toString() {
return "OrderItemPK [orderId=" + orderId + ", lineItemId=" + lineItemId + "]";
}
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;
@Column(name="ORDER_ID", insertable=false, updatable=false)
private long orderId;
@Column(name="LINE_ITEM_ID")
private long lineItemId;
public OrderItemPK() {
}
public long getOrderId() {
return this.orderId;
}
public void setOrderId(long orderId) {
this.orderId = orderId;
}
public long getLineItemId() {
return this.lineItemId;
}
public void setLineItemId(long lineItemId) {
this.lineItemId = lineItemId;
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof OrderItemPK)) {
return false;
}
OrderItemPK castOther = (OrderItemPK)other;
return (this.orderId == castOther.orderId);
}
public int hashCode() {
//System.out.print("PK hashCode");
final int prime = 31;
int hash = 17;
hash = hash * prime + ((int) (this.orderId ^ (this.orderId >>> 32)));
hash = hash * prime + ((int) (this.lineItemId ^ (this.lineItemId >>> 32)));
return hash;
}
@Override
public void readExternal(PofReader in) throws IOException {
this.orderId = in.readLong(0);
this.lineItemId = in.readLong(1);
}
@Override
public void writeExternal(PofWriter out) throws IOException {
out.writeLong(0, this.orderId);
out.writeLong(1, this.lineItemId);
}
//@Override
public int compareTo(Object o) {
OrderItemPK i = (OrderItemPK) o;
if(this.getOrderId() < i.getOrderId())
return -1;
if(this.getOrderId() > i.getOrderId())
return 1;
return 0;
}
}
ProductInformation.java
@Entity
@Table(name="PRODUCT_INFORMATION")
@NamedQuery(name="ProductInformation.findAll", query="SELECT p FROM ProductInformation p")
public class ProductInformation implements Serializable, PortableObject {
private static final long serialVersionUID = 1L;
@Id
@Column(name="PRODUCT_ID")
private long productId;
@Column(name="CATALOG_URL")
private String catalogUrl;
@Column(name="CATEGORY_ID")
private int categoryId;
@Column(name="LIST_PRICE")
private float listPrice;
@Column(name="MIN_PRICE")
private float minPrice;
@Column(name="PRODUCT_DESCRIPTION")
private String productDescription;
@Column(name="PRODUCT_NAME")
private String productName;
@Column(name="PRODUCT_STATUS")
private String productStatus;
@Column(name="SUPPLIER_ID")
private long supplierId;
@Column(name="WEIGHT_CLASS")
private int weightClass;
//bi-directional many-to-one association to OrderItem
@OneToMany(mappedBy="productInformation")
private List<OrderItem> orderItems;
public ProductInformation() {
}
public List<OrderItem> getOrderItems() {
return this.orderItems;
}
public void setOrderItems(List<OrderItem> orderItems) {
this.orderItems = orderItems;
}
public OrderItem addOrderItem(OrderItem orderItem) {
getOrderItems().add(orderItem);
orderItem.setProductInformation(this);
return orderItem;
}
public OrderItem removeOrderItem(OrderItem orderItem) {
getOrderItems().remove(orderItem);
orderItem.setProductInformation(null);
return orderItem;
}
@Override
public void readExternal(PofReader in) throws IOException {
this.productId = in.readLong(0);
this.catalogUrl = in.readString(1);
this.categoryId = in.readInt(2);
this.listPrice = in.readFloat(3);
this.minPrice = in.readFloat(4);
this.productDescription = in.readString(5);
this.productName = in.readString(6);
this.productStatus = in.readString(7);
this.supplierId = in.readLong(8);
this.weightClass = in.readInt(9);
}
@Override
public void writeExternal(PofWriter out) throws IOException {
out.writeLong(0, this.productId);
out.writeString(1, this.catalogUrl);
out.writeInt(2, this.categoryId);
out.writeFloat(3, this.listPrice);
out.writeFloat(4, this.minPrice);
out.writeString(5, this.productDescription);
out.writeString(6, this.productName);
out.writeString(7, this.productStatus);
out.writeLong(8, this.supplierId);
out.writeInt(9, this.weightClass);
}
}
persistence.java
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="OrderEntryPrj" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>entities.Order</class>
<class>entities.OrderItem</class>
<class>entities.OrderItemPK</class>
<class>entities.ProductInformation</class>
<properties>
<property name="eclipselink.target-server" value="None"/>
<property name="javax.persistence.jdbc.url" value="zzz:1521:orcl"/>
<property name="javax.persistence.jdbc.user" value="oe"/>
<property name="javax.persistence.jdbc.password" value="oracle"/>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
<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.connection" value="false"/>
<property name="eclipselink.logging.exceptions" value="true"/>
<property name="eclipselink.cache.shared.default" value="false"/>
</properties>
</persistence-unit>
</persistence>
2. Create the Cache Configuration File for JPA
The 2nd step is to create coherence config file.
<cache-config>
<caching-scheme-mapping>
<cache-mapping>
<!-- Set the name of the cache to be the entity name. -->
<cache-name>Order</cache-name>
<!-- Configure this cache to use the following defined scheme. -->
<scheme-name>jpa-distributed</scheme-name>
</cache-mapping>
<cache-mapping>
<!-- Set the name of the cache to be the entity name. -->
<cache-name>OrderItem</cache-name>
<!-- Configure this cache to use the following defined scheme. -->
<scheme-name>jpa-distributed</scheme-name>
</cache-mapping>
</caching-scheme-mapping>
<caching-schemes>
<distributed-scheme>
<scheme-name>jpa-distributed</scheme-name>
<service-name>JpaDistributedCache</service-name>
<serializer>
<instance>
<class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name>
<init-params>
<init-param>
<param-type>String</param-type>
<param-value>pof-config.xml</param-value>
</init-param>
</init-params>
</instance>
</serializer>
<backing-map-scheme>
<read-write-backing-map-scheme>
<internal-cache-scheme>
<local-scheme/>
</internal-cache-scheme>
<!-- Define the cache scheme. -->
<cachestore-scheme>
<class-scheme>
<class-name>
com.tangosol.coherence.jpa.JpaCacheStore
</class-name>
<init-params>
<!-- This param is the entity name. -->
<init-param>
<param-type>java.lang.String</param-type>
<param-value>{cache-name}</param-value>
</init-param>
<!-- This param is the fully qualified entity class. -->
<init-param>
<param-type>java.lang.String</param-type>
<param-value>entities.{cache-name}</param-value>
</init-param>
<!-- This param should match the value of the -->
<!-- persistence unit name in persistence.xml. -->
<init-param>
<param-type>java.lang.String</param-type>
<param-value>OrderEntryPrj</param-value>
</init-param>
</init-params>
</class-scheme>
</cachestore-scheme>
</read-write-backing-map-scheme>
</backing-map-scheme>
<autostart>true</autostart>
</distributed-scheme>
<!-- The below is required for extendes client. For this example, this can be removed -->
<proxy-scheme>
<service-name>ExtendTcpProxyService</service-name>
<acceptor-config>
<tcp-acceptor>
<local-address>
<address>localhost</address>
<port>9099</port>
</local-address>
</tcp-acceptor>
<serializer>
<instance><class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name></instance>
</serializer>
</acceptor-config>
<autostart>true</autostart>
</proxy-scheme>
</caching-schemes>
</cache-config>
3. Create a Java Client to Interact with Data Object
package client;
public class OrderClient {
public static void main(String[] args) {
System.out.println("Accessing Coherence Cache from Java - Order Client");
Scanner in = new Scanner(System.in);
OrderItem item = null;
System.out.print("Enter Order ID to fetch: ");
String orderId = in.nextLine();
NamedCache<Object, Object> orderCache = CacheFactory.getCache("Order");
Order order1 = (Order) orderCache.get(Long.parseLong(orderId));
System.out.println("[Order ID: " + order1.getOrderId() + ", Order Mode: " + order1.getOrderMode()
+ ", Order Total: $" + order1.getOrderTotal() + ", Products Ordered = {");
int size = order1.getOrderItems().size();
for (int i = 0; i < size; i++) {
item = order1.getOrderItems().get(i);
System.out.println("ItemID: " + item.getId().getLineItemId() + ", Qty: " + item.getQuantity() + ", Product Name: " + item.getProductInformation().getProductName() + "#");
}
System.out.println("}");
order1.setOrderMode("online");
orderCache.put(orderId, order1);
Order order2 = (Order) orderCache.get(orderId);
System.out.println("Order Status:" + order2.getOrderStatus() + "<->Order Mode:" + order2.getOrderMode()
+ "<->:Order Item Size: " + order1.getOrderItems().size());
}
}
PS: Both Client & Server are using same coherence config in this example.
No comments:
Post a Comment