gpt4 book ai didi

java - OpenJpa 查询缓存在空值的情况下不刷新

转载 作者:搜寻专家 更新时间:2023-11-01 02:39:42 24 4
gpt4 key购买 nike

我在 OpenJpa 二级缓存中遇到了一些问题。大多数时候缓存是有效的,但在一种特殊情况下它不起作用。这是一个不工作的场景,当您的代码结果为空值时,它会将其存储到缓存中,然后永远不会清除该值。尽管它仅在查询返回值时才清除值。

这是我为从数据库中获取值而编写的代码,

List<PartnerapiworkflowEntity> partnerapiworkflowEntityList = null;
try {
partnerapiworkflowEntityList = entityManager.createQuery("select p from someentity p where p.id = :Id and p.name = :name and " +
"p.code = :Code and p.operationname = :operationName")
.setParameter("Id", Id)
.setParameter("name", name)
.setParameter("code", Code)
.setParameter("operationName", operationName).getResultList();//.getSingleResult();
if(partnerapiworkflowEntityList != null && partnerapiworkflowEntityList.size() > 0){
return Boolean.TRUE;
}
} catch (NoResultException ne) {
logger.severe("some logging info.");
}
finally {
// entityManager.detach(partnerapiworkflowEntity);
}

这是刷新缓存的代码。

try{
entityManager.flush();
entityManager.clear();
entityManager.getEntityManagerFactory().getCache().evictAll();
//((JpaEntityManager)entityManager.getDelegate()).getServerSession().getIdentityMapAccessor().invalidateAll();
entityManager.flush();

} catch (Exception e){
throw e;
}

这是persistence.xml代码

<property name="openjpa.jdbc.DBDictionary" value="mysql"/>
<property name="openjpa.DataCache" value="true(EnableStatistics=true, CacheSize=10000, SoftReferenceSize=0, EvictionSchedule='+10')"/>
<property name="openjpa.QueryCache" value="true(EvictPolicy='timestamp')"/>
<!--<property name="openjpa.jdbc.QuerySQLCache" value="true(EnableStatistics=true)"/>-->
<property name="javax.persistence.sharedCache.mode" value="ENABLE_SELECTIVE"/>

<property name="openjpa.Instrumentation" value="jmx(Instrument='DataCache,QueryCache,QuerySQLCache')"/>
<property name="openjpa.MetaDataRepository" value="Preload=true"/>

<property name="openjpa.Log" value="SQL=Trace" />
<property name="openjpa.ConnectionFactoryProperties" value="PrintParameters=true" />

当查询始终返回值时一切正常。当它返回空值时问题就开始了。然后第一次存储在缓存中,然后它永远不会刷新。

我正在使用 OpenJpa2 和 Hibernate。

最佳答案

此问题首先是在 OpenJPA 2.2.2 中观察到的.网上查了下trunk上有一个修复的缺陷,和二级缓存有关(https://issues.apache.org/jira/browse/OPENJPA-2285)

但是后来在https://issues.apache.org/jira/browse/OPENJPA-2522又发现了这个问题


解决方案:

目前还没有确定。但是他们给出了一些绕过的方案。

  1. 禁用查询缓存

要禁用查询缓存(默认),设置 openjpa.QueryCache属性为假:

<property name="openjpa.QueryCache" value="false"/>
  1. 通过配置sql查询缓存为false

    • 指定自定义缓存类:

      <property name="openjpa.jdbc.QuerySQLCache" value="com.mycompany.MyCustomCache"/>

    • 使用非托管缓存:

      <property name="openjpa.jdbc.QuerySQLCache" value="false"/>

    • 使用非托管缓存:

      <property name="openjpa.jdbc.QuerySQLCache" value="all"/>


  1. Open JPA - L2 Cache Issue and Workaround

This tutorial depicts your problem same to same. Here you can get the clear conception of occuring this error.

它给出了一个解决方案,你必须要保留相关数据。这样NullPointerException不会出现。数据必须一致,直到 OpenJPA 无法解决问题。 :D


  1. Several mechanisms are available to the application to bypass SQLcaching for a JPQL query.

用户应用程序可以通过在 OpenJPA 的 EntityManager SPI 接口(interface)上调用以下方法,在持久性上下文的整个生命周期内禁用准备好的 SQL 缓存:

OpenJPAEntityManagerSPI.setQuerySQLCache(boolean) 
  1. 插件属性 openjpa.jdbc.QuerySQLCache可以配置为排除某些 JPQL 查询,如下所示。

    <property name="openjpa.jdbc.QuerySQLCache" value="true(excludes='select c from Company c;select d from Department d')"/>

永远不会缓存 JPQL 查询 select c from Company cselect d from Department d .

Root Cause Analysis:

查询缓存存储查询执行返回的对象 ID。当您运行查询时,JPA 会根据查询属性和启动时使用的参数组合一个键,并检查缓存的查询结果。如果找到,则查找缓存结果中的对象 ID,并返回生成的具有持久性的对象。否则,将针对数据库启动查询,并将查询加载的对象 ID 放入缓存中。在查询启动时返回的列表被完全遍历之前,不会缓存对象 ID 列表。

IBM Recommendation:

L2 caching increases the memory consumption of the application, therefore, it is important to limit the size of the L2 cache. There is also a possibility of stale data for updated objects in a clustered environment. Configure L2 caching for read-mostly, infrequently modified entities. L2 caches are not recommended for frequently and concurrently updated entities.

资源链接:

Open JPA 2.4.0 Caching Reference Guide

关于java - OpenJpa 查询缓存在空值的情况下不刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36642798/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com