JPA Eclipselink数据库更改通知不会使缓存条目无效

我有两个使用Eclipselink 2.4.2进行持久化的Java 1.7应用程序。 一个应用程序是在Glassfish 3.1.2.2中运行的JEE应用程序,另一个是Java SE应用程序。 这些应用程序读取和写入相同的数据,因此可能存在过时的JPA缓存条目。 我试图使用Oracle DCN来解决过时的缓存问题。

我已经按照上面的链接中的描述配置了我的persistence.xml:

   org.eclipse.persistence.jpa.PersistenceProvider jdbc/DRMS              

然而,我仍然得到陈旧的缓存条目。 如果一个应用程序提交对数据库的更改,则第二个应用程序仍会看到其旧的过时缓存条目,而不是新的更改。 使用调试器,我已经确认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值始终为null,因此失效代码永远不会运行。

如果我在调试器中检查IdentityMapManager对象,我可以看到预期的实体在缓存中。 然而,CacheId的查找每次都失败(返回null)。

任何帮助表示赞赏。

问题已经解决。 它是由persistence.xml中“eclipselink.target-database”属性的值引起的。 我们将它设置为“Oracle”,将其更改为“Oracle11”解决了这个问题。 显然,直到Oracle版本11才添加DCNfunction,并且Eclipselink的行为取决于该值。