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 just 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
The following software is required to run this example:
- Oracle 11.2 database - download link
- ant (1.7 was used, but other versions should also work) - download link
- EclipseLink 2.4 - download link
- Database event example - download link - SVN
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" />
The database user must have the XXX privilege granted on the database.
Running the example
- Configure paths to server in the <example>/build.xml (JEE_HOME, JEE_SERVER, JEE_HOST, JEE_USER, JEE_PASSWORD)
- Install Oracle database (or use existing database, ensure the database)
- Configure database in <example>/build.xml (DB_DRIVER, DB_URL, DB_USER, DB_PASSWORD)
- Configure persistence.xml in <example>src/meta-inf/
- Install ant (or uses existing ant install)
- Build the application
- Run "ant"
- this will compile the example code and build the employee.ear
- Run the example
- Run "ant example"
- This should give the following output.
Buildfile: build.xml example: BUILD SUCCESSFUL