我正在使用 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
注释的entites。
但是,如果我再次运行该命名查询,则在没有@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
注释的实体从未首先进入查询缓存,那就太好了。