1 Configuring Coherence for JPA

The Java Persistence API (JPA) is the standard for object-relational mapping (ORM) and enterprise Java persistence. This chapter describes the following:

Note:

Only resource-local and bootstrapped entity managers can be used with Coherence API and JPA. Container-managed entity managers and those that use Java Transaction Architecture (JTA) transactions are not currently supported.

This chapter also provides a brief introduction to JPA on the Grid, where JPA applications use TopLink Grid to interact directly with the database. TopLink Grid, in turn, uses the Coherence data grid to store some or all of the domain model. For a detailed discussion of JPA on the Grid, see the Integration Guide for Oracle TopLink with Coherence Grid.

This chapter contains the following sections:

1.1 API for Native Coherence and Coherence JPA CacheStore and CacheLoader

Oracle Coherence provides its own implementations of the CacheLoader and CacheStore classes which can be used with JPA. The JpaCacheLoader and JpaCacheStore classes can use any JPA implementation to load and store entities to and from a data store. The entities must be mapped to the data store and a JPA persistence unit configuration must exist. A JPA persistence unit is defined as a logical grouping of user-defined entity classes that can be persisted and their settings.

Coherence also provides a default cache configuration file called coherence-cache-config.xml. The JPA run-time configuration file, persistence.xml, and the default JPA Object-Relational mapping file, orm.xml, are typically provided by the JPA implementation.

Table 1-1 describes the default JPA implementations provided by Coherence.

Table 1-1 JPA-Related CacheStore and CacheLoader API Included with Coherence

Class Name Description

com.tangosol.net.cache.CacheLoader

A JCache cache loader.

com.tangosol.net.cache.CacheStore

A JCache cache store. The CacheStore interface extends CacheLoader.

com.tangosol.coherence.jpa.JpaCacheLoader

The JPA implementation of the Coherence CacheLoader interface. Use this class as a load-only implementation. It can use any JPA implementation to load entities from a data store. The entities must be mapped to the data store and a JPA persistence unit configuration must exist.

Use the JpaCacheStore class for a full load and store implementation.

com.tangosol.coherence.jpa.JpaCacheStore

The JPA implementation of the Coherence CacheStore interface. Use this class as a full load and store implementation. It can use any JPA implementation to load and store entities to and from a data store. The entities must be mapped to the data store and a JPA persistence unit configuration must exist.

Note: The persistence unit is assumed to be set to use RESOURCE_LOCAL transactions.


1.2 Using the Default Coherence JPA

To use Coherence JPA to load and store objects to the database:

  1. Obtain a JPA Provider Implementation. The provider implementation allows you to map, query, and store Java objects to a database.

  2. Configure a Coherence JPA Cache Store. The JPA cache store configuration maps database entities to Java objects.

1.2.1 Obtain a JPA Provider Implementation

A JPA provider allows you to work directly with Java objects, rather then with SQL statements. You can map, store, update and retrieve data, and the provider will perform the translation between database entities and Java objects.

A JPA provider is not included in the Coherence distribution, but you can obtain one. Although the Coherence JPA cache store works with any JPA-compliant implementation, Oracle recommends using EclipseLink JPA, the reference implementation for the JPA 2.0 specification. EclipseLink JPA is available from Eclipse at the following URL:

http://www.eclipse.org/eclipselink

Oracle TopLink and TopLink Grid for Coherence integration include EclipseLink as their JPA implementations. For more information about TopLink and to download it, go to the following URL:

http://www.oracle.com/technology/products/ias/toplink/index.html

1.2.2 Configure a Coherence JPA Cache Store

JPA is a standard API for mapping, querying, and storing Java objects to a database. The characteristics of the different JPA implementations can differ, however, when it comes to caching, threading, and overall performance. TopLink provides a high-performance JPA implementation with many advanced features.

Coherence provides a default entity-based cache store implementation, JpaCacheStore, and a corresponding cache loader, JpaCacheLoader. You can find additional information in the Javadoc for these classes.

To configure a Coherence JpaCacheStore:

  1. Map the Persistent Classes

  2. Configure JPA

  3. Configure a Coherence Cache for JPA

  4. Configure the Persistence Unit

1.2.2.1 Map the Persistent Classes

Map the entity classes to the database. This will allow you to load and store objects through the JPA cache store. JPA mappings are standard, and can be specified in the same way for all JPA providers.

You can map entities either by annotating the entity classes or by adding an orm.xml or other XML mapping file. See the JPA provider documentation for more information about how to map JPA entities.

1.2.2.2 Configure JPA

Edit the persistence.xml file to create the JPA configuration. This file contains the properties that dictate run-time operation.

Set the transaction type to RESOURCE_LOCAL and provide the required JDBC properties for your JPA provider (such as driver, url, user, and password) with the appropriate values for connecting and logging into your database. List the classes that are mapped using JPA annotations in <class> elements. Example 1-1 illustrates a sample persistence.xml file with the typical properties that you can set.

Example 1-1 Sample persistence.xml File for JPA

<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance" version="1.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="EmpUnit" transaction-type="RESOURCE_LOCAL"> 
    <provider>
        org.eclipse.persistence.jpa.PersistenceProvider
    </provider>
    <class>com.oracle.coherence.handson.Employee</class>
    <properties>
        <property name="eclipselink.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
        <property name="eclipselink.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
        <property name="eclipselink.jdbc.user" value="scott"/>
        <property name="eclipselink.jdbc.password" value="tiger"/>
    </properties>
</persistence-unit>
</persistence>

1.2.2.3 Configure a Coherence Cache for JPA

Create a coherence-cache-config.xml file to override the default Coherence settings and define the JpaCacheStore caching scheme. The caching scheme should include a <cachestore-scheme> element that lists the JpaCacheStore class and includes the following parameters.

  • The entity name of the entity being stored. Unless it is explicitly overridden in JPA, this is the unqualified name of the entity class. Example 1-2 uses the built-in Coherence macro {cache-name} that translates to the name of the cache that is constructing and using the cache store. This works because a separate cache must be used for each type of persistent entity and Coherence ensures that the name of each cache is set to the name of the entity that is being stored in it.

  • The fully qualified name of the entity class. If the classes are all in the same package and use the default JPA entity names, then you can again use the {cache-name} macro for the part that is variable across the different entity types. In this way, the same caching scheme can be used for all of the entities that are cached within the same persistence unit.

  • The persistence unit name. This should be the same as the name specified in the persistence.xml file.

The various named caches are then directed to use the JPA caching scheme. Example 1-2 is a sample coherence-cache-config.xml file that defines a NamedCache class named Employee that caches instances of the Employee class. To define additional entity caches for more classes, add more <cache-mapping> elements to the file.

Example 1-2 Assigning Named Caches to a JPA Caching Scheme

<cache-config>
  <caching-scheme-mapping>
    <cache-mapping>
      <!-- Set the name of the cache to be the entity name.  -->
      <cache-name>Employee</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>
      <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>com.acme.{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>EmpUnit</param-value>
                </init-param>
              </init-params>
            </class-scheme>
          </cachestore-scheme>
        </read-write-backing-map-scheme>
      </backing-map-scheme>
    </distributed-scheme>
  </caching-schemes>
</cache-config>

1.2.2.4 Configure the Persistence Unit

When using the JpaCacheStore class, configure the persistence unit to ensure that no changes are made to entities when they are inserted or updated. Any changes made to entities by the JPA provider are not reflected in the Coherence cache. This means that the entity in the cache will not match the database contents. In particular, entities should not use ID generation, for example, @GeneratedValue, to obtain an ID. IDs should be assigned in application code before an object is put into Coherence. The ID is typically the key under which the entity is stored in Coherence.

Optimistic locking (for example, @Version) should not be used because it might lead to the failure of a database transaction commit transaction. See Read-Through, Write-Through, Write-Behind, and Refresh-Ahead Caching in Oracle Coherence Getting Started Guide and Sample CacheStore in Oracle Coherence Developer's Guide for more information about how a cache store works, and how to set up your database schema.

When using either the JpaCacheStore or JpaCacheLoader class, L2 ("shared") caching should be disabled in your persistence unit. See the documentation for your provider. In Oracle TopLink, this can be specified on an individual entity with @Cache(shared=false) or as the default in the persistence.xml file with the following property:

<property name="eclipselink.cache.shared.default" value="false"/>

When using EclipseLink with TopLink Grid, the TopLink Grid implementations will automatically disable L2 caching, optimistic lock checking, and versioning. Essentially, TopLink Grid implementations understand the cache store context in which the persistence unit is being deployed and adjust the configuration accordingly.

1.3 Using Coherence Caches Backed by TopLink Grid

Figure 1-1 illustrates the relationship between the client application (which employs Coherence APIs), the Coherence cache, TopLink Grid, and the database.

Figure 1-1 Coherence with TopLink Grid Approach

Traditional Coherence approach.

1.3.1 API for Coherence with TopLink Grid Configurations

The TopLink Grid cache store and cache loader implementations are shipped in the toplink-grid.jar file. TopLink Grid uses the standard JPA run-time configuration file persistence.xml and the JPA mapping file orm.xml. The Coherence cache configuration file coherence-cache-config.xml must be specified to override the default Coherence settings and to define the cache store caching scheme.

The TopLink Grid cache store and cache loader classes which are optimized for EclipseLink JPA and designed for use by Coherence applications, are in the oracle.eclispelink.coherence.standalone package. Table 1-2 describes these classes.

Table 1-2 TopLink Grid Classes to build Coherence with TopLink Grid Applications

Class Name Description

EclipseLinkJPACacheLoader

Provides JPA-aware versions of the Coherence CacheLoader class.

EclipseLinkJPACacheStore

Provides JPA-aware versions of the Coherence CacheStore class.


1.3.2 Examples of Coherence with TopLink Grid Configurations

In the cache configuration (coherence-cache-config.xml) define the cache, as illustrated in Example 1-3. For TopLink Grid, you have to define only two parameters:

  • The name of the cache for the entity being stored. Unless explicitly overridden in JPA this is the entity name that, by default, is the unqualified name of the entity class. In Example 1-3, the name of the cache is Employee. You can use the built-in Coherence macro {cache-name} to supply the name of the cache that is constructing and using the cache store.

  • The name of the persistence unit containing the entity being stored. In Example 1-3, employee-pu is a persistence unit defined in the META-INF/persistence.xml file that includes the Employee entity.

    To define more entity caches, add additional <cache-mapping> elements.

Example 1-3 Configuring the Cache for Coherence with TopLink Grid

<cache-config>
  <caching-scheme-mapping>
    <cache-mapping>
      <cache-name>Employee</cache-name>
      <scheme-name>distributed-eclipselink</scheme-name>
    </caching-scheme-mapping>
  </caching-scheme-mapping>
  <caching-schemes>
    <distributed-scheme>
      <scheme-name>distributed-eclipselink</scheme-name>
      <service-name>EclipseLinkJPA</service-name>
      <backing-map-scheme>
        <read-write-backing-map-scheme>
          <internal-cache-scheme>
            <local-scheme />
          </internal-cache-scheme>
          <!-- 
            Define the cache scheme. 
          -->
          <cachestore-scheme>
            <class-scheme>
            <!-- 
              Because the client code is using Coherence API, use the "standalone" version of the cache loader. 
            -->
              <class-name>oracle.eclipselink.coherence.standalone.EclipseLinkJPACacheStore</class-name>
              <init-params>

           <!-- This parameter is the name of the cache containing the entity. -->
                <init-param>
                  <param-type>java.lang.String</param-type>
                  <param-value>{cache-name}</param-value>
                </init-param>

            <!-- This parameter is the persistence unit name. -->
                <init-param>
                  <param-type>java.lang.String</param-type>
                  <param-value>employee-pu</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>

1.4 Using Coherence as the TopLink Grid Cache

Note:

This section provides only an introduction to using Coherence as the cache for TopLink Grid. See Integration Guide for Oracle TopLink with Coherence Grid for more information.

Oracle TopLink Grid is a feature of Oracle TopLink that provides integration between the EclipseLink JPA and Coherence. Standard JPA applications interact directly with their primary data store, typically a relational database. However, with TopLink Grid you can store some or all of your domain model in the Coherence data grid. This configuration is also known as JPA on the Grid.

You can easily configure TopLink Grid to use Coherence as the primary data store, execute queries against the grid, and allow Coherence to manage the persistence of new and modified data. Coherence provides the layer between JPA and the data store, where direct database calls can be offloaded from every application instance. This makes it possible for clustered application deployments to scale beyond the bounds of standard database operations.

These are the typical TopLink Grid configurations that applications can use:

  • Coherence Shared L2 Cache configuration, which uses Coherence as the TopLink L2 (Shared) cache. This configuration applies the Coherence data grid to JPA applications that rely on database-hosted data that cannot be entirely preloaded into a Coherence cache. Some reasons why it might not be able to be preloaded include extremely complex queries that exceed the feature set of Coherence Filters, third-party database updates that create stale caches, reliance on native SQL queries, stored procedures or triggers, and so on.

    In this configuration, you can scale TopLink up into large clusters while avoiding the requirement to coordinate local L2 caches. Updates made to entities are available in all Coherence cluster members immediately, upon committing a transaction.

  • Coherence Read configuration, which is optimal for entities that require fast access to large amounts of (fairly stable) data and must write changes synchronously to the database. In these entities, cache warming would be used to populate the Coherence cache, but individual queries could be directed to the database if necessary.

  • Coherence Read/Write configuration, which is optimal for applications that require fast access to large amounts of (fairly stable) data and perform relatively few updates. This configuration can be combined with a Coherence cache store using write-behind to improve application response time by performing database updates asynchronously.

See the Oracle TopLink Grid page on the Oracle Technology Network for more information about configuring Coherence for TopLink Grid.

http://www.oracle.com/technology/products/ias/toplink/tl_grid.html