Уведомление об изменении базы данных JPA Eclipselink не делает запись кэша недействительной

У меня есть два приложения Java 1.7, использующих Eclipselink 2.4.2 для сохранения. Одно приложение является приложением JEE, запущенным в Glassfish 3.1.2.2, а другое - приложением Java SE. Эти приложения читают и записывают одни и те же данные, поэтому существует возможность устаревших записей кэша JPA. Я пытаюсь использоватьOracle DCN решить проблему устаревшего кэша.

Я настроил свой файл persistence.xml, как описано в ссылке выше:

<?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
             http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">
  <persistence-unit name="drms-persistence-unit" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/DRMS</jta-data-source>
    <properties>
      <property name="eclipselink.cache.database-event-listener"
                value="org.eclipse.persistence.platform.database.oracle.dcn.OracleChangeNotificationListener"/>
      <property name="eclipselink.target-server" value="SunAS9"/>
      <property name="eclipselink.target-database" value="Oracle"/>
      <property name="eclipselink.logging.level" value="INFO"/>
      <property name="eclipselink.logging.parameters" value="true"/>
      <property name="eclipselink.jdbc.native-sql" value="true"/>
      <property name="eclipselink.jdbc.batch-writing" value="Oracle-JDBC"/>
      <property name="eclipselink.jdbc.cache-statements" value="true"/>
      <property name="eclipselink.jdbc.cache-statements.size" value="200"/>
    </properties>
  </persistence-unit>
</persistence>

И все же я все еще получаю устаревшие записи кэша. Если одно приложение фиксирует изменение в базе данных, второе приложение все еще видит свою старую устаревшую запись в кэше, а не новое изменение. Используя отладчик, я подтвердил, что OracleChangeNotificationListener получает события базы данных, но, похоже, он фактически ничего не делает недействительным в кеше.

Eclipselink OracleChangeNotificationListener регистрирует следующий приемник для получения событий изменения базы данных Oracle:

public void onDatabaseChangeNotification(DatabaseChangeEvent changeEvent) {
    databaseSession.log(SessionLog.FINEST, SessionLog.CONNECTION, "dcn_change_event", changeEvent);
    if (changeEvent.getTableChangeDescription() != null) {
        for (TableChangeDescription tableChange : changeEvent.getTableChangeDescription()) {
            ClassDescriptor descriptor = OracleChangeNotificationListener.this.descriptorsByTable.get(new DatabaseTable(tableChange.getTableName()));
            if (descriptor != null) {
                CacheIndex index = descriptor.getCachePolicy().getCacheIndex(fields);                                
                for (RowChangeDescription rowChange : tableChange.getRowChangeDescription()) {
                    CacheId id = new CacheId(new Object[]{rowChange.getRowid().stringValue()});
                    CacheKey key = databaseSession.getIdentityMapAccessorInstance().getIdentityMapManager().getCacheKeyByIndex(
                            index, id, true, descriptor);
                    if (key != null) {
                        if ((key.getTransactionId() == null) || !key.getTransactionId().equals(changeEvent.getTransactionId(true))) {
                            databaseSession.log(SessionLog.FINEST, SessionLog.CONNECTION, "dcn_invalidate", key.getKey(), descriptor.getJavaClass().getName());
                            key.setInvalidationState(CacheKey.CACHE_KEY_INVALID);
                        }
                    }
                }
            }
        }
    }
}

Этот слушатель вызывается каждый раз, когда мы вносим изменения в базу данных. Однако значение CacheKey, которое просматривается, всегда равно нулю, и поэтому код аннулирования никогда не запускается.

Если я проверяю объект IdentityMapManager в отладчике, я вижу, что ожидаемый объект находится в кеше. И все же поиск по CacheId каждый раз завершается неудачей (возвращает ноль).

Любая помощь приветствуется.

Ответы на вопрос(1)

Ваш ответ на вопрос