Skip Headers
Oracle® Coherence Tutorial for Oracle Coherence
Release 3.7

Part Number E18692-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

8 Using JPA with Coherence

In this chapter, you learn how to use Java Persistence API (JPA) to perform object-relational mapping. This chapter contains the following sections:

You must have a working version of the Oracle Database Express Edition (also known as the OracleXE database) installed on your system. If you do not have the database, you can download it from this URL:

http://www.oracle.com/technology/software/products/database/xe/index.html

8.1 Introduction

A major enhancement in Enterprise JavaBeans (EJB) technology is the addition of JPA, which simplifies the entity persistence model and adds capabilities, such as persistence for Java SE, that were not in earlier EJB technologies.

JPA defines how relational data is mapped to Java objects (persistent entities), the way that these objects are stored in a relational database so that they can be accessed at a later time, and the continued existence of an entity's state even after the application that uses it ends. In addition to simplifying the entity persistence model, the JPA standardizes object-relational mapping.

To determine how data is stored within a Coherence cluster, a backing map is used. By default, Coherence uses a memory-based backing map. To persist data, there are several backing map implementations.

The JPA implementation used in this exercise provides Object Relational Mapping (ORM) from the Java world to the database world. It also allows you to use standard Coherence get and put methods, and have Coherence calls translated into database calls using JPA and Oracle TopLink (based on the open source EclipseLink project).

8.2 Mapping Relational Data to Java Objects with JPA

In this exercise, you use Eclipse to perform the following tasks:

  1. Unlock the OracleXE Database

  2. Download the JPA Libraries

  3. Configure the Project for JPA

  4. Create the JPA Persistence Unit and Entity Beans

  5. Edit the persistance.xml File

  6. Create the Cache Configuration File for JPA

  7. Create a Cache Server Start-Up Configuration

  8. Create a Class to Interact with the Data Object

  9. Create a Run Configuration for RunEmployeeExample

  10. Run the JPA Example

8.2.1 Unlock the OracleXE Database

Unlock the HR account in your pre-installed OracleXE database.

You must have the OracleXE database installed on your system and be able to access the HR schema. To unlock the HR account, follow these steps:

  1. Navigate to Start then All Programs then Oracle Database Express Edition then Run SQL Command Line.

  2. Enter connect system as sysdba, and then enter welcome1 when prompted for the password. (Note: your user name is system and your password is welcome1.)

    Figure 8-1 Connecting to the Database

    Connecting to the Database
    Description of "Figure 8-1 Connecting to the Database"

  3. Enter the command to unlock the account:

    alter user hr identified by hr account unlock;
    

    Figure 8-2 Unlocking the Database Account

    Unlocking the Database Account
    Description of "Figure 8-2 Unlocking the Database Account"

8.2.2 Download the JPA Libraries

This exercise requires the org.eclipse.persistence.* and the javax.persistence files to be present in your system. You can obtain these files through the Eclipse IDE.

  1. Select Help then Eclipse Marketplace.

  2. In the Eclipse Marketplace dialog box, enter EclipseLink in the Find field and click Go.

  3. Select the EclipseLink SDK, as illustrated in Figure 8-3, and follow installation instructions. The required persistence files will be installed in the eclipse\plugins directory.

    Figure 8-3 EclipseLink SDK in the Eclipse Marketplace

    EclipseLink SDK in the Eclipse Marketplace
    Description of "Figure 8-3 EclipseLink SDK in the Eclipse Marketplace"

8.2.3 Configure the Project for JPA

Create a new project in Eclipse IDE called JPA. See "Creating a New Project in the Eclipse IDE" for detailed information.

  1. In the Eclipse IDE, click Window then Open Perspective then Other to open the Open Perspective dialog box. Select the JPA perspective, as illustrated in Figure 8-4.

    Figure 8-4 Selecting the JPA Perspective in the Open Perspective Dialog Box

    The JPA Perspective in the Open Perspective Dialog Box
    Description of "Figure 8-4 Selecting the JPA Perspective in the Open Perspective Dialog Box"

  2. Select File then New then JPA Project. Enter JPA as the project name. Ensure that the default location points to home\oracle\workspace\JPA. Click Modify in the Configuration field to open the Project Facets dialog box.

  3. Select the Oracle Coherence facet. The JPA facet should already be selected.

  4. Click Save As in the Configuration field. Enter JPAConfiguration in the Save Preset dialog box and click OK. The contents of the Project Facets dialog box should look similar to Figure 8-5.

    Figure 8-5 Project Facets for a JPA Project

    Project Facets for a JPA Project
    Description of "Figure 8-5 Project Facets for a JPA Project"

    The contents of the New JPA Project dialog box should look similar to Figure 8-6. Click Next to go to the Java page.

    Figure 8-6 Contents of the New JPA Project Dialog Box

    Contents of the JPA Projects Dialog Box
    Description of "Figure 8-6 Contents of the New JPA Project Dialog Box"

  5. Click Next in the Java page to accept the default output folder location.

  6. The Coherence37 user library should already be selected in the Coherence page. Click Next.

  7. In the JPA Facet page, select EclipseLink 2.1.x in the Platform drop-down list. Click the Download library icon to download the EclipseLink files. In the Download Library dialog box, select EclipseLink 2.1.2 - Helios, as illustrated by Figure 8-7.

    Figure 8-7 Downloading the EclipseLink JPA Library

    Downloading the EclipseLink JPA Library
    Description of "Figure 8-7 Downloading the EclipseLink JPA Library"

  8. Click Next to accept the license agreement, then click Finish.

    After downloading the library, the JPA Facet page should look similar to

    Figure 8-8 EclipseLink Libraries Added to the JPA Facet Page

    EclipseLink Libraries Added to the JPA Facet Page
    Description of "Figure 8-8 EclipseLink Libraries Added to the JPA Facet Page"

  9. Create a connection to the Oracle XE Database. Click Add connection.

    1. In Connection Profile dialog box, select Oracle Database Connection. and enter XE_HR in the Name field, as illustrated in Figure 8-9. Click Next.

      Figure 8-9 Connection Profile Page

      Connection Profile page
      Description of "Figure 8-9 Connection Profile Page"

    2. Select Oracle Database 10g Driver Default in the Drivers field. Edit the General tab. Enter hr in the User name field and hr in the Password field. Select the Save Password check box. Enter localhost in the Host field. Select the Connect when the wizard completes check box. Click Test Connection button. The test should return an alert box with a success message, as illustrated in Figure 8-10. Click OK, then Next.

      Figure 8-10 The New Connection Profile Dialog Box and the Success Message

      New Connection Profile Dialog Box and Success Message
      Description of "Figure 8-10 The New Connection Profile Dialog Box and the Success Message"

    3. In the JPA Facet page, click Add driver library to build path, then click Finish.

8.2.4 Create the JPA Persistence Unit and Entity Beans

A persistence unit provides an easy way to identify the set of metadata files, classes, and JARs that contain all classes that need to be persisted as a group. The name of the persistence unit is used to identify it. Entity beans are Enterprise Java beans that contain persistent data, and that can be saved in persistent data stores. The JPA entity bean can belong to a persistence unit. The persistence unit is described by the persistence.xml file.

To create the JPA persistence unit and the JPA entity beans:

  1. Right-click the JPA project and select New then select Entities from Tables. The Select Tables dialog box opens.

  2. Select the EMPLOYEES table, as illustrated in Figure 8-11 and click Next.

    Figure 8-11 Selecting the Database Tables

    Selecting the Database Tables
    Description of "Figure 8-11 Selecting the Database Tables"

  3. In the Table Associations page, illustrated in Figure 8-12, click Next to accept the defaults.

    Figure 8-12 Associations for the EMPLOYEES Table

    Associations for the EMPLOYEES Table
    Description of "Figure 8-12 Associations for the EMPLOYEES Table"

  4. In the Customize Default Entity Generation page, select Collection properties type java.uitil.List, Enter com.oracle.handson in the Package field.

    When you are finished, the Customize Default Entity Generation page should look similar to Figure 8-13. Click Next.

    Figure 8-13 Customize Default Entity Generation Page

    Customize Default Entity Generation
    Description of "Figure 8-13 Customize Default Entity Generation Page"

  5. In the Customize Individual Entities page, accept the defaults as illustrated in and click Finish to generate the JPA Entities.

    Figure 8-14 Customize Individual Entities Page

    Customize Individual Entities Dialog Box
    Description of "Figure 8-14 Customize Individual Entities Page"

8.2.5 Edit the persistance.xml File

The persistence.xml file defines one or more persistence units. Use the persistence.xml Editor tool in the Eclipse IDE to edit the persistence.xml file.

  1. Open the persistence.xml file in the Eclipse editor.

  2. Click the General tab. Enter the name of the persistence provider. This will be org.eclipse.persistence.jpa.PersistenceProvider.

    Figure 8-15 General Tab in the persistence.xml Editor

    General Tab iin the persistence.xml Editor
    Description of "Figure 8-15 General Tab in the persistence.xml Editor"

  3. In the Connection tab, select Resource Local from the Transaction type drop down list.

    In JDBC connection properties section, click Populate from connection link. The values in this field will be provided from the database connection you defined in "Configure the Project for JPA". The Connection Properties tab should look similar to Figure 8-16.

    Figure 8-16 Connection Properties Tab in the persistence.xml Editor

    Connection Properties Tab
    Description of "Figure 8-16 Connection Properties Tab in the persistence.xml Editor"

  4. Inspect the Properties tab. The contents should look similar to Figure 8-17.

    Figure 8-17 Properties Tab in the persistence.xml Editor

    Properties Tab in the persistence.xml Editor
    Description of "Figure 8-17 Properties Tab in the persistence.xml Editor"

  5. Open the Source tab. The persistence.xml file should look similar to Example 8-1.

    Example 8-1 Generated persistence.xml File

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="2.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_2_0.xsd">
      <persistence-unit name="JPA" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>com.oracle.handson.Employees</class>
        <properties>
          <property name="eclipselink.target-server" value="None"/>
          <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
          <property name="javax.persistence.jdbc.user" value="hr"/>
          <property name="javax.persistence.jdbc.password" value="hr"/>
          <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
        </properties>
      </persistence-unit>
    </persistence>
    

8.2.6 Create the Cache Configuration File for JPA

Create a cache configuration file for the JPA project.

  1. Right click coherence-cache-config.xml file and select Open.

  2. Enter the code illustrated in Example 8-2. Use Save As to save the file as jpa-cache-config.xml. The file will be saved to the home\oracle\workspace\JPA\src folder.

    Example 8-2 Cache Configuration for JPA

    <?xml version="1.0" encoding="windows-1252" ?>
    <cache-config>
      <caching-scheme-mapping>
        <cache-mapping>
          <!-- Set the name of the cache to be the entity name  -->
          <cache-name>Employees</cache-name>
          <!-- Configure this cache to use the scheme defined below  -->
          <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>
          <backing-map-scheme>
            <read-write-backing-map-scheme>
              <!--
          Define the cache scheme
          -->
              <internal-cache-scheme>
                <local-scheme/>
              </internal-cache-scheme>
              <cachestore-scheme>
                <class-scheme>
                  <class-name>com.tangosol.coherence.jpa.JpaCacheStore</class-name>
                  <init-params>
                    <!--
                This param is the entity name
                This param is the fully qualified entity class
                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>{cache-name}</param-value>
                    </init-param>
                    <init-param>
                      <param-type>java.lang.String</param-type>
                      <param-value>com.oracle.handson.{cache-name}</param-value>
                    </init-param>
                    <init-param>
                      <param-type>java.lang.String</param-type>
                      <param-value>JPA</param-value>
                    </init-param>
                  </init-params>
                </class-scheme>
              </cachestore-scheme>
            </read-write-backing-map-scheme>
          </backing-map-scheme>
          <autostart>true</autostart>
        </distributed-scheme>
      </caching-schemes>
    </cache-config>
    
  3. Delete the original coherence-cache-config.xml file from the Project Explorer.

8.2.7 Create a Cache Server Start-Up Configuration

Create a configuration to start the cache server for the JPA project.

  1. Right click the project and select Run As then Run Configurations. In the Run Configurations dialog box, Enter JPACacheServer in the Name field.

  2. In the Main tab, click Browse in the Project field and select the JPA project in the Project Selection dialog box. Select the Include system libraries when searching for a main class checkbox and click Search. Enter DefaultCacheServer in the Select Type field and select com.tangosol.net.DefaultCacheServer. Click OK. The Main tab should look similar to Figure 8-18.

    Figure 8-18 Main Tab for the JPA Cache Server

    Main Tab for the JPA Cache Server
    Description of "Figure 8-18 Main Tab for the JPA Cache Server"

  3. In the General tab of the Coherence tab, identify the path to the cache configuration file under Topology. Click the Browse button to navigate to the Absolute file path of the JPA cache configuration file C:\home\oracle\workspace\JPA\src\jpa-cache-config.xml. Select Enabled (cache server) under Local storage. Enter a unique value, such as 3155, for the Cluster port.

    In the Other tab, ensure that the tangosol.pof.config item is set to the default pof-config.xml.

  4. In the Common tab, select Shared file and browse to the \JPA project.

  5. In the Classpath tab, click User Entries then Add External JARs to add the coherence-jpa.jar file to the list. Click Apply.

    The Classpath tab should look similar to Figure 8-19.

    Figure 8-19 Classpath Tab for the JPA Cache Server Executable

    Classpath Tab for the JPA Cache Server
    Description of "Figure 8-19 Classpath Tab for the JPA Cache Server Executable"

8.2.8 Create a Class to Interact with the Data Object

Create a new class in the JPA project to interact with the Employees object. The objective of the class will be to change the value of an employee's salary.

  1. Create a new class with a main method called RunEmployeeExample. See "Creating a Java Class" for detailed information.

  2. Create the code to perform the following:

    1. Get an employee using the EMPLOYEE_ID attribute. EMPLOYEE_ID is a long data type.

    2. Display the salary.

    3. Give the employee a 10% pay raise.

    4. Get the value again to confirm the pay raise.

    Example 8-3 illustrates a possible implementation of the RunEmployeeExample class.

    Example 8-3 Sample Employee Class File

    package com.oracle.handson;
    
    import com.tangosol.net.CacheFactory;
    import com.tangosol.net.NamedCache;
    import java.math.BigDecimal;
    
    public class RunEmployeeExample 
        {
        public RunEmployeeExample() 
        {
        }
    
        public static void main(String[] args) 
            {
            long empId = 190L;  // emp 190 - Timothy Gates
            
            NamedCache employees = CacheFactory.getCache("Employees");
            
            Employees emp = (Employees)employees.get(empId);   
            
            System.out.println("Employee " + emp.getFirstName() + " " + 
                            emp.getLastName() + ", salary = $" + emp.getSalary() );
            
            // give them a 10% pay rise
            emp.setSalary(emp.getSalary().multiply(BigDecimal.valueOf(1.1)));
            
            employees.put(empId, emp);
            
            Employees emp2 = (Employees)employees.get(empId);
            
            System.out.println("New Employee details are " + emp2.getFirstName() + " " + emp2.getLastName() + ", salary = $" + emp2.getSalary() );
           }
    }
    

8.2.9 Create a Run Configuration for RunEmployeeExample

To create a run configuration, modify the run-time properties and edit the class path in Eclipse.

  1. Right click RunEmployeeExample.java in the Project Explorer and choose Run As then Run Configurations. In the Run Configurations dialog box, click New launch configurations icon. Enter RunEmployeeExample in the Name field.

  2. In the Main tab, click Browse and select the JPA project. In the Main class field, click Search and choose com.oracle.handson.RunEmployeeExample. Click Apply.

  3. In the General tab of the Coherence tab, browse to the C:\home\oracle\workspace\JPA\src\jpa-cache-config.xml file in the Cache configuration descriptor field. Select the Disabled (cache client) button. Enter 3155 in the Cluster port field. Click Apply.

  4. In the Other tab, ensure that the default pof-config.xml appears in the tangosol.pof.config field.

  5. In the Classpath tab, click Add External JARs to add the coherence-jpa.jar file to User Entries.

  6. Use the Up and Down buttons to move Coherence37 to the top of Bootstrap Entries. Click Apply.

    The Classpath tab should look similar to Figure 8-20.

    Figure 8-20 Classpath Tab for the RunEmployeeExample Program

    Classpath Tab for the RunEmployeeExample Program
    Description of "Figure 8-20 Classpath Tab for the RunEmployeeExample Program"

8.2.10 Run the JPA Example

Now that the Employees class has been annotated to persist to the database using JPA, and you have included the persistence.xml file to tell JPA where your database is, Coherence employs a CacheStore implementation that uses JPA to load and store objects in the database. When you use the get(Object key) method, the following happens:

  • Coherence looks for the entry with the key.

  • if the entry is not already in the cache, or if it is expired from the cache, then coherence calls the backing map, which uses jpa and eclipselink, to retrieve the data.

  • if the entry is in the cache, coherence returns the entry directly to the application without going through eclipselink. when you use the put(object key,object value) method, coherence uses jpa through eclipselink to persist any changes to the database.

Click Run to run the RunEmployeeExample configuration. The output from the program should look similar to Example 8-4.

Example 8-4 Output from the RunEmployeeExample Program

...
TcpRing{Connections=[1]}
IpMonitor{AddressListSize=0}
 
2011-03-15 19:29:10.307/1.296 Oracle Coherence GE 3.7.0.0 <D5> (thread=Invocation:Management, member=2): Service Management joined the cluster with senior service member 1
2011-03-15 19:29:10.401/1.390 Oracle Coherence GE 3.7.0.0 <D5> (thread=DistributedCache:JpaDistributedCache, member=2): Service JpaDistributedCache joined the cluster with senior service member 1
Employee Timothy Gates, salary = $17736.19 
New Employee details are Timothy Gates, salary = $19509.809 
...

The response from the cache server displays a successful login to retrieve information from the database, as illustrated in Example 8-5.

Example 8-5 Cache Server Response to Logging In to the Database

2011-03-15 19:28:54.573/5.203 Oracle Coherence GE 3.7.0.0 <D5> (thread=Invocation:Management, member=1): Service Management joined the cluster with senior service member 1
2011-03-15 19:28:54.839/5.469 Oracle Coherence GE 3.7.0.0 <D5> (thread=DistributedCache:JpaDistributedCache, member=1): Service JpaDistributedCache joined the cluster with senior service member 1
2011-03-15 19:28:54.886/5.516 Oracle Coherence GE 3.7.0.0 <Info> (thread=main, member=1): 
Services
  (
  ClusterService{Name=Cluster, State=(SERVICE_STARTED, STATE_JOINED), Id=0, Version=3.7, OldestMemberId=1}
  InvocationService{Name=Management, State=(SERVICE_STARTED), Id=1, Version=3.1, OldestMemberId=1}
  PartitionedCache{Name=JpaDistributedCache, State=(SERVICE_STARTED), LocalStorage=enabled, PartitionCount=257, BackupCount=1, AssignedPartitions=257, BackupPartitions=0}
  )
 
Started DefaultCacheServer...
 
2011-03-15 19:29:10.261/20.891 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2011-03-15 19:29:10.065, Address=130.35.99.213:8090, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:896, Role=OracleHandsonRunEmployeeExample) joined Cluster with senior member 1
2011-03-15 19:29:10.307/20.937 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member 2 joined Service Management with senior member 1
2011-03-15 19:29:10.417/21.047 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member 2 joined Service JpaDistributedCache with senior member 1
[EL Info]: 2011-03-15 19:29:13.151--ServerSession(33017287)--EclipseLink, version: Eclipse Persistence Services - 2.1.2.v20101206-r8635
[EL Info]: 2011-03-15 19:29:13.589--ServerSession(33017287)--file:/C:/home/oracle/workspace/JPA/build/classes/_JPA login successful
2011-03-15 19:29:15.073/25.703 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): TcpRing disconnected from Member(Id=2, Timestamp=2011-03-15 19:29:10.065, Address=130.35.99.213:8090, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:896, Role=OracleHandsonRunEmployeeExample) due to a peer departure; removing the member.
2011-03-15 19:29:15.073/25.703 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member 2 left service Management with senior member 1
2011-03-15 19:29:15.073/25.703 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member 2 left service JpaDistributedCache with senior member 1
2011-03-15 19:29:15.073/25.703 Oracle Coherence GE 3.7.0.0 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2011-03-15 19:29:15.073, Address=130.35.99.213:8090, MachineId=49877, Location=site:us.oracle.com,machine:tpfaeffl-lap7,process:896, Role=OracleHandsonRunEmployeeExample) left Cluster with senior member 1