8 Using JPA with Coherence

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

This exercise assumes that you have a working version of the Oracle Database 10g Express Edition (also known as the OracleXE database) installed on your system. If you do not have the database, you can download it here:


8.1 Introduction

A major enhancement in 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 the EJB 2.1 technology.

JPA deals with the way 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.

You use the JPA implementation within this lesson. This implementation provides Object Relational Mapping (ORM) from the Java world to the database world, allowing you to use the standard Coherence get or put, and have the 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, use JDeveloper to perform the following:

  • Create a connection to the HR schema in the OracleXE database.

  • Automatically generate JPA objects for the EMPLOYEES table.

  • Modify cache-server.cmd to point to the sample JPA cache-config.xml.

  1. Unlock the OracleXE Database

  2. Create the Database Connection and Create the JPA Persistence Unit

  3. Create the JPA Persistence Unit and Entity Beans

  4. Create the Cache Configuration File for JPA

  5. Create a Cache Server Start-Up File

  6. Modify JPA Project Properties

  7. Create a Class to Interact with the Data Object

  8. Run the JPA Example

8.2.1 Unlock the OracleXE Database

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

It is assumed that you have the OracleXE database installed on your machine and can access the HR schema. To unlock the HR account, perform the following steps:

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

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

    Figure 8-1 Connecting to the Database

    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

8.2.2 Configure the Project for JPA

Create a new project in JDeveloper called JPA. See "Creating a New Project in an Existing Application" if you need detailed information.

  1. Set the default Java Options in Run/Debug/Profile of the Project Properties to the appropriate log level and to disable local storage.

    -Dtangosol.coherence.distributed.localstorage=false  -Dtangosol.coherence.log.level=3
  2. Ensure that the classpath points to the full path for the coherence.jar file:


8.2.3 Create the Database Connection and Create the JPA Persistence Unit

Follow these steps to connect to the HR database schema and create the JPA persistence unit.

  1. In the Application Resources section of the navigator, right-click Connections, select New Connection, and then Database Connection.

  2. Enter the details to connect to your HR schema and click OK.

    • Connection Name: XE_HR

    • Connection Type: Oracle (JDBC)

    • Username: hr

    • Password: hr

    • Click Test Connection.

    This should display "Success!"

    Click OK.

    Figure 8-3 Defining the Database Connection

    Defining the Database Connection

8.2.4 Create the JPA Persistence Unit and Entity Beans

Follow these steps to create the JPA persistence unit and the Entity Beans.

  1. Right-click the JPA project and select New. Under Business Tier, select EJB, and then select Entities from Tables. Click OK.

    Figure 8-4 Creating EJB Entity Beans

    Creating EJB Entity Beans
  2. In the Create Entities from Tables window, select EJB 3.0 --JPA Entities, and then click Next.

    Figure 8-5 Specifying the EJB Version

    Specifying the EJB Version
  3. Click New to create a persistence unit. (Each persistence unit defines a set of classes and their mapping characteristics when persisting them.) Enter the following details and click OK.

    Name: JPA

    JTA Datasource Name: <leave blank>

    Non-JTA Datasource Name: <leave blank>

    Database Platform: Oracle

    Server Platform: None

    Click OK. When the Create Entities from Tables screen returns, click Next.

    Figure 8-6 Defining the Persistence Unit

    Defining the Persistance Unit
  4. Select the Online Database Connection option and click Next.

    Figure 8-7 Creating Entity Beans from Table Data

    Creating Entity Beans from Table Data
  5. In the Database Connection Details window, click Next.

    Figure 8-8 Choosing the Database Connection

    Choosing the Database Connection
  6. Click the Query button to display the tables illustrated in Figure 8-9. Select the EMPLOYEES table and shuttle it to the Selected column. Click Next.

    Figure 8-9 Choosing the Table Data for the Entity Bean

    Choosing the Table Data for the Entity Bean
  7. Accept the default General Options and click Next.

    Figure 8-10 Choosing General Options for the Entity

    Choosing General Options for the Entity
  8. Accept the default Entity Class Details and click Next.

    Figure 8-11 Specifying the Entity Details

    Specifying the Entity Details
  9. A Summary page appears. Click Finish to create the Entity bean. You should see messages similar to Figure 8-12 in the EJB Log window of the navigator.

    Figure 8-12 Generating EJB Entity Beans: the EJB Log Window

    Generating EJB Entity Beans
  10. Replace the contents of persistence.xml with the code in Example 8-1 and save the file. Ensure that the connection details match your database connection details. The persistence.xml file appears in the c:\home\oracle\labs\JPA\src\META-INF folder.

    Example 8-1 persistance.xml File Contents

    <persistence xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance" version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="JPA" transaction-type="RESOURCE_LOCAL">
            <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
            <property name="javax.persistence.jdbc.password" value="hr"/>
            <property name="javax.persistence.jdbc.user" value="hr"/>

8.2.5 Create the Cache Configuration File for JPA

Open a text editor and create a file named jpa-cache-config.xml. Use the code illustrated in Example 8-2. Save the file in the home\oracle\labs\ directory.

Example 8-2 Cache Configuration for JPA

<?xml version="1.0" encoding="windows-1252" ?>
      <!-- Set the name of the cache to be the entity name  -->
      <!-- Configure this cache to use the scheme defined below  -->
      Define the cache scheme
            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

8.2.6 Create a Cache Server Start-Up File

Create a cache server file for the JPA project. You can use the cache-server.cmd file as a starting point.

  1. Open a terminal window. Navigate to the /oracle/product/coherence/bin directory and copy the cache-server.cmd file to jpa-cache-server.cmd.

    cp cache-server.cmd jpa-cache-server.cmd
  2. Edit jpa-cache-server.cmd. Declare the cache configuration file in Java_OPTS:

  3. Add the following CLASSPATH to the -cp argument: C:\home\oracle\labs\JPA\classes;

  4. You must also add the following JAR files to the CLASSPATH:

    • Coherence JPA libraries: C:\oracle\product\coherence\lib\coherence-jpa.jar

    • EclipseLink persistence libraries: C:\oracle\product\modules\org.eclipse.persistence_1.0.0.0_2-0.jar

    • Oracle JDBC JAR, ojdbc6.jar, for database connectivity: C:\oracle\product\wlserver_10.3\server\lib\ojdbc6.jar

    • Coherence TopLink libraries: C:\oracle\product\coherence\lib\coherence-toplink.jar

    • javax.persistence.* libraries: C:\oracle\product\modules\javax.persistence_1.0.0.0_1-0-2.jar

    The classpath should look similar to the following:


    Example 8-3 illustrates a modified jpa-cache-server.cmd file:

    Example 8-3 Modified jpa-cache-server.cmd File

    @echo off
    @rem This will start a cache server
    @rem specify the Coherence installation directory
    set coherence_home=c:\oracle\product\coherence
    @rem specify the JVM heap size
    set memory=512m
    if not exist "%coherence_home%\lib\coherence.jar" goto instructions
    if "%java_home%"=="" (set java_exec=java) else (set java_exec=%java_home%\bin\java)
    set java_opts="-Xms%memory% -Xmx%memory% -Dtangosol.coherence.cacheconfig=\home\oracle\labs\jpa-cache-config.xml"
    "%java_exec%" -server -showversion "%java_opts%" -cp "%coherence_home%\lib\coherence.jar;C:\home\oracle\labs\JPA\classes;C:\oracle\product\coherence\lib\coherence-jpa.jar;C:\oracle\product\modules\org.eclipse.persistence_1.0.0.0_2-0.jar;C:\oracle\product\wlserver_10.3\server\lib\ojdbc6.jar;C:\oracle\product\oracle_common\modules\oracle.toplink_11.1.1\eclipselink-dbwsutils.jar;C:\oracle\product\modules\javax.persistence_1.0.0.0_1-0-2.jar" com.tangosol.net.DefaultCacheServer %1
    goto exit
    echo Usage:
    echo   ^<coherence_home^>\bin\cache-server.cmd
    goto exit
    @echo on
  5. Save the jpa-cache-server.cmd file and ensure that all other cache servers are stopped. Run jpa-cache-server.cmd.


8.2.7 Modify JPA Project Properties

Follow these steps to modify the run time properties and edit the classpath in JDeveloper.

  1. Edit the JPA Project Properties and modify the Run/Debug/Profile configuration. Append the following line to the existing Java Options.

  2. Add additional CLASSPATH entries to the existing project properties.

    Navigate to Tools then Project Properties then Libraries and Classpath. Use the Add JAR/Directory and Add Library buttons to add any of the following JAR files and libraries that are not already on the CLASSPATH (Note: the coherence.jar file should already be present):

    • coherence-jpa.jar to provide a reference to the JpaCacheStore.

    • TopLink predefined JDeveloper library. This will provide the required EclipseLink JARs and APIs

    • EcilpseLink Persistence JAR file for the Eclipse persistence API: C:\oracle\product\modules\org.eclipse.persistence_1.0.0.0_2-0.jar

    • Oracle JDBC predefined JDeveloper library for database connectivity

    • Oracle XML Parser v2 predefined JDeveloper library for interpreting XML

    • Java Persistence JAR file for the persistence API: C:\oracle\product\modules\javax.persistence_1.0.0.0_1-0-2.jar

    • Java EE 1.5 API. Included by default.

    The Libraries and Classpath screen should look similar to Figure 8-13:

    Figure 8-13 Adding JARs and Libraries to the Classpath

    Adding JARs to the Classpath

8.2.8 Create a Class to Interact with the Data Object

Create a new class in the JPA project to interact with the Employee object.

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

  2. Create the code to perform the following:

    1. Get an employee using EMPLOYEE_ID. EMPLOYEE_ID should be a long data type.

    2. Display the salary.

    3. Give them a 10% pay raise.

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

    Example 8-4 illustrates a possible solution.

    Example 8-4 Sample Employee Class File

    package com.oracle.handson;
    import com.tangosol.net.CacheFactory;
    import com.tangosol.net.NamedCache;
    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() * 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 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 to the database. When you use the get(Object key) method, the following happens:

  • Coherence looks for the entry with the key.

  • If the entry has not already been cached, or if it is expired from the cache, then Coherence asks 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 put(Object Key,Object Value), Coherence uses JPA through EclipseLink to persist any changes to the database.

  1. Compile the project files if you have not already done so.

  2. Run RunEmployeeExample.java.

The output should look similar to the text illustrated Figure 8-14.

Figure 8-14 Results from the RunEmployeeExample Application

Results from the RunEmployeeExample Application