OpenJPA QueryCache缓存不可缓存的实体

OpenJPA QueryCache缓存不可缓存的实体,jpa,caching,openjpa,Jpa,Caching,Openjpa,我正在将glassfish 3.2.2与OpenJPA 2.2.1一起使用 在my persistence.xml中,我有: <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode> <properties> <property name="openjpa.QueryCache" value="true(CacheSize=10000, SoftReferenceSize=1000)"

我正在将glassfish 3.2.2与OpenJPA 2.2.1一起使用

在my persistence.xml中,我有:

<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
        <property name="openjpa.QueryCache" value="true(CacheSize=10000, SoftReferenceSize=1000)"/>
        <property name="openjpa.DataCache" value="true(CacheSize=20000, SoftReferenceSize=1000)"/>
        <property name="openjpa.RuntimeUnenhancedClasses" value="unsupported"/>
</properties>
EJB:

@NamedQueries ({ @NamedQuery(name="MyEntity.getByName", query="select e from MyEntity e where e.name = :name")})

@Entity
public class MyEntity
{
  @Id
  @Column
  private long id;

  @Column
  private String name;
}
@Stateless
public class MyEJB
{
  @PersistenceContext
  EntityManager em;

  public MyEntity getEntityByName(String name) {
    TypedQuery<MyEntity> namedQuery = em.createNamedQuery("MyEntity.getByName", MyEntity.class);
    namedQuery.setParameter("name", name); 
    return namedQuery.getSingleResult(); 
  }
}
@无状态
公共类
{
@持久上下文
实体管理器;
公共MyEntity getEntityByName(字符串名称){
typedquerynamedquery=em.createNamedQuery(“MyEntity.getByName”,MyEntity.class);
namedQuery.setParameter(“name”,name);
返回namedQuery.getSingleResult();
}
}
经进一步调查:

这个问题可能很难发现,因为只要查询返回相同的ID,不管它是否在查询缓存中,都会得到相同的结果

例如,如果我只是更新数据库中返回的行的数据,那么它将返回新数据

在我的例子中,批处理过程是删除行,然后用新id重新插入新行。因此,查询缓存存储行的原始id,因此当我运行查询时,它现在返回null,因为该id不再存在。如果我清除了查询缓存,那么它将正确地返回新行


因此,如果没有
@Cacheable
注释的实体从一开始就没有进入查询缓存,那就太好了。

您如何确定结果来自QueryCache?我在实体管理器外部更改了数据库,但它仍然会带回陈旧的数据。但是,如果我直接使用em.find,它会返回新数据。我还使用org.apache.openjpa.persistence.OpenJPAPersistence.cast(em.getEntityManagerFactory()).getQueryResultCache()直接查看了查询缓存,并使用IntelliJ检查了对象,找到了缓存中的查询和实体。请,编写伪代码以更好地解释您正在运行的场景。但是,还有一个批处理过程在实体管理器之外更新数据库。因此,对于在实体管理器之外从未更新过的实体,我希望它们使用查询缓存,以及我用@Cacheable注释过的那些实体。然后,由于我为共享缓存指定了ENABLE_SELECTIVE,我希望所有其他实体都不要使用数据缓存或查询缓存。