1

我正在使用glassfish 3.2.2OpenJPA 2.2.1

在我的 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>

我只希望@Cacheable缓存具有注释的实体。

但是,在对没有@Cacheable注释的实体运行命名查询之后,如果我再次运行该命名查询,它将从查询缓存中返回结果。

如果我对实体进行直接查找,它不会从数据缓存中获取实体。

那么为什么@Cacheable阻止一个实体被放入数据缓存,却不阻止它被放入查询缓存呢?

有没有办法防止所有没有@Cacheable注释的实体被放入查询缓存中?

伪代码

实体类:

@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;
}

EJB:

@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(); 
  }
}

经进一步调查:

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

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

在我的情况下,批处理正在删除该行,然后重新插入具有新 ID 的新行。所以查询缓存存储了行的原始 id,所以当我运行查询时,它现在返回 null,因为该 id 不再存在。如果我清除查询缓存,那么它会正确带回新行。

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

4

0 回答 0