This section contains the following tasks to enable shared caching in a JPA environment:
The solution presumes that you are working with an Oracle 11gR2 (11.2) or higher database that contains the tables that you are interested in.
Among other permissions, the database user must be granted the CHANGE
NOTIFICATION
privilege. To do this, you must have a DBA privilege, such as SYS
, or have your database administrator apply it:
grant change notification to
user
The following example illustrates granting the change notification privilege to user SCOTT
.
...
define user="SCOTT"
define pass="tiger"
grant create session, alter session to &&user
/
grant resource, connect to &&user
/
grant select any dictionary to &&user
/
grant select any table to &&user
/
grant change notification to &&user
/
...
Ensure that the eclipselink.jar
EclipseLink library, the ojdbc6.jar
JDBC library, the persistence.jar
JPA library, and the domain classes are present on the classpath.
By default, all entities in the domain will participate in change notification. There are several different ways to limit the entities that will participate. For example, the entity classes can be indicated by the <entity class...>
element in the orm.xml
file, indicated with the <exclude-unlisted-classes>
element in the persistence.xml
file, or contained in a JAR file.
Note: The |
Entity classes can also be excluded by using a Cache
annotation attribute in the Java files. For more information, see Exclude Classes from Change Notification (Optional).
Another way to identify the entity classes is to use the <class>
element in the persistence.xml
file. The following example indicates that the Order
, OrderLine
, and Customer
classes in the model
package will participate in change notification. For an example of a complete persistence.xml
file, see Example 20-1.
... <class>model.Order</class> <class>model.OrderLine</class> <class>model.Customer</class> ...
Use the eclipselink.cache.database-event-listener
property to identify the database event listener. The org.eclipse.persistence.platform.database.oracle.dcn.OracleChangeNotificationListener
class is the listener for Continuous Query Notification. This allows the EclipseLink cache to be invalidated by database events.
The following example illustrates the eclipselink.cache.database-event-listener
property configured with the OracleChangeNotificationListener
class. For an example of a complete persistence.xml
file, see Example 20-1.
... <properties> <property name="eclipselink.cache.database-event-listener" value="org.eclipse.persistence.platform.database.oracle.dcn.OracleChangeNotificationListener"/> </properties> ...
Note that you can also use:
<property name="eclipselink.cache.database-event-listener" value="DCN">
Example 20-1 illustrates an example of a complete persistence.xml
file. The classes that will participate in change notification are the Order
, OrderLine
, and Customer
classes from the model
package. The eclipselink.cache.database-event-listener
property is set to the full path of the OracleChangeNotificationListener
class.
Note: A |
Example 20-1 Sample persistence.xml File
<?xml version="1.0" encoding="UTF-8"?> <persistence 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 persistence_2_0.xsd" version="2.0"> <persistence-unit name="acme" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <class>model.Order</class> <class>model.OrderLine</class> <class>model.Customer</class> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="eclipselink.cache.database-event-listener" value="DCN"/> </properties> </persistence-unit> </persistence>
Typically, to participate in change notification, no changes are needed to the Java classes which correspond to database tables. However, setting optimistic locking with the @Version
annotation is strongly suggested.
If you want to exclude classes that are listed in the persistence unit, you can tag them in the Java files. EclipseLink tracks changes only to the primary table. If you want changes to secondary tables to also be tracked, you can indicate this in the Java files.
Oracle strongly suggests that you use optimistic locking: writes on stale data will fail and automatically invalidate the cache. Include an @Version
annotation in your entity; the version column in the primary table will always be updated, and the older version of the object will always be invalidated.
In Example 20-2 the @Version
annotation is defined for the entity Customer
. Note that getters and setters are defined for the version
variable.
Example 20-2 Defining the @Version Annotation
... @Entity @Table(name="DBE_CUSTOMER") public class Customer implements Serializable { @Id @GeneratedValue(generator="CUST_SEQ") @TableGenerator(name="CUST_SEQ") @Column(name="CUST_NUMBER") private long id;@Version
private long version;
...public long getVersion()
{return version;
}public void setVersion(long version) {
this.version = version;
} ...
Use the databaseChangeNotificationType
attribute of the Cache
annotation to identify the classes for which you do not want change notifications. To exclude a class from change notification, set the attribute to DatabaseChangeNotificationType.NONE
, as illustrated in the following example.
...
@Entity
@Cache(databaseChangeNotificationType=DatabaseChangeNotificationType.NONE)
public class Order {
...
EclipseLink tracks changes only to the primary table. If any updates occur in a secondary table, EclipseLink will not invalidate the object. If you want changes to secondary tables to be tracked as well, add the @Version
annotation to the entity.
CQN listens only for events from the primary table. It does not track changes in secondary tables, or relationships tables. The reason for this is that Oracle CQN only tracks the ROWID
, so there is no correlation from the ROWID
of the primary, secondary and relationship tables. Thus, to receive events when a secondary or relationship table changes, the version in the primary table must change so that the event is returned.