Jump to: navigation, search

Difference between revisions of "EclipseLink/Examples/JPA/DCN"

(Running the example)
(Running the example)
Line 60: Line 60:
 
# Configure paths in <example>/build.xml (JDBC_LIB, JPA_LIB, ECLIPSELINK_LIB)
 
# Configure paths in <example>/build.xml (JDBC_LIB, JPA_LIB, ECLIPSELINK_LIB)
 
# Configure database URL and user/password in persistence.xml in <example>src/meta-inf/
 
# Configure database URL and user/password in persistence.xml in <example>src/meta-inf/
 +
# Ensure database user has CHANGE NOTIFICATION privilege in the database
 
# Install ant (or uses existing ant install)
 
# Install ant (or uses existing ant install)
 
# Build the application
 
# Build the application

Revision as of 14:07, 24 April 2012

Overview

EclipseLink supports a shared (L2) object cache that avoids database access for objects and their relationships. This cache is enabled by default which is normally not a problem, unless the database is modified directly by other applications, or by the same application on other servers in a clustered environment.

There are many solutions to caching in a shared environment, including:

  • disable the shared cache
  • only cache read-only objects
  • set a cache invalidation timeout
  • use refreshing on objects/queries when fresh data is required
  • use optimistic locking (writes on stale data will fail, and will automatically invalidate the cache)
  • using a distributed cache (such as Oracle TopLink Grid with Oracle Coherence)
  • using cache coordination
  • using database events to invalidate changed data

This example gives an overview of the database events option.

EclipseLink 2.4 adds support for a DatabaseEventListener to receive database events. EclipseLink provides an OracleChangeNotificationListener to integrate with Oracle's Database Event Notification support (also known as Query Change Notification). The Oracle database added this support in the 10.2 release, but did not fully enable the JDBC support for it until the 11.2 release. The OracleChangeNotificationListener uses Oracle's DCN support to listen to database row changes and invalidate the cache for the objects that are changed on the database. This allows for caching to be used in JPA, even if other applications, even non-Java applications are accessing and updating the same database. This can also be used as an alternative to cache coordination in a cluster.

Integrated support for other databases is not currently provided. If another database supports an event mechanism, or allows triggers to raise events, then it is possible to implement your own DatabaseEventListener to perform cache invalidation. In previous versions of the Oracle database it is possible to perform cache invalidation through triggers and Oracle AQ.

This example demonstrates enabling database event driven cache invalidation using Oracle DCN with the Oracle 11.2 database. The example runs in Java SE, but any other Java EE or EclipseLink supported environment should also work.

If you encounter any issues in running this example, please discuss, here

Prerequisites

The following software is required to run this example:

Configuring the example

Database events can be configured using persistence unit properties (in your persistence.xml). It can also be configured in code using a SessionCustomizer, or using System properties (which match the persistence unit properties). This example will use persistence unit properties.

<property name="eclipselink.cache.database-event-listener" value="org.eclipse.persistence.platform.database.oracle.dcn.OracleChangeNotificationListener" />

By default all entity classes are registered for database change notification. To exclude a class from change notification the @Cache annotation is used.

@Entity
@Cache(databaseChangeNotificationType=DatabaseChangeNotificationType.NONE)
public class Order {
  ...
}

The database user must have the CHANGE NOTIFICATION privilege granted on the database.

GRANT CHANGE NOTIFICATION TO SCOTT

Running the example

  1. Install Oracle database (or use existing database)
  2. Configure paths in <example>/build.xml (JDBC_LIB, JPA_LIB, ECLIPSELINK_LIB)
  3. Configure database URL and user/password in persistence.xml in <example>src/meta-inf/
  4. Ensure database user has CHANGE NOTIFICATION privilege in the database
  5. Install ant (or uses existing ant install)
  6. Build the application
    1. Run "ant"
    2. this will compile the example code
  7. Run the example
    1. Run "ant example"
    2. This should give the following output.
     [java] Starting example.
     [java]
     [java]
     [java] Selecting all customer on application #2.
     [java]
     [java]
     [java] Inserting new customer on application #1.
     [java]
     [java]
     [java] Selecting new customer on application #2.
     [java]
     [java]
     [java] Customer name on application #1: Test1
     [java] Customer name on application #2: Test1
     [java]
     [java]
     [java] Updating customer name to 'Test2' on application #1.
     [java]
     [java]
     [java] Selecting customer on application #2.
     [java]
     [java]
     [java] Customer name on application #1: Test2
     [java] Customer name on application #2: Test2
     [java]
     [java]
     [java] Updating customer name to 'Test3' through direct native SQL query on application #1.
     [java]
     [java]
     [java] Selecting customer on application #2.
     [java]
     [java]
     [java] Finding customer on application #1.
     [java]
     [java]
     [java] Customer name on application #1: Test3
     [java] Customer name on application #2: Test3
     [java]
     [java]
     [java] Updating customer name to 'Test4' through batch update query on application #1.
     [java]
     [java]
     [java] Selecting customer on application #2.
     [java]
     [java]
     [java] Finding customer on application #1.
     [java]
     [java]
     [java] Customer name on application #1: Test4
     [java] Customer name on application #2: Test4
     [java]
     [java]
     [java] Deleting customer on application #1.
     [java]
     [java]
     [java] Selecting customer on application #2.
     [java]
     [java]
     [java] Customer not found on application #2.
     [java]
     [java]
     [java] Inserting new customer 'Test5' on application #2.
     [java]
     [java]
     [java] Selecting customer on application #1.
     [java]
     [java]
     [java] Updating customer name to 'Test6' on application #1.
     [java]
     [java]
     [java] Selecting customer on application #2.
     [java]
     [java]
     [java] Customer name on application #1: Test6
     [java] Customer name on application #2: Test6
     [java]
     [java]
     [java] Example finished.

Links