我正在使用glassfish 3.2.2和OpenJPA 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
注释的实体一开始就永远不会进入查询缓存,那就太好了。