EclipseLink Cache未被缓存

时间:2016-01-28 14:44:28

标签: caching eclipselink jpa-2.0

@NamedQuery(
            name=DBConstants.SERVICE_BY_ID, query="select s from Service s where s.id= :id",
            hints={
                    @QueryHint(name = QueryHints.QUERY_RESULTS_CACHE, value = HintValues.TRUE),
                    @QueryHint(name = QueryHints.QUERY_RESULTS_CACHE_SIZE, value = "500")
            })

我在每个查询请求中使用不同的实体管理器。

Query query = em.createNamedQuery(DBConstants.SERVICE_BY_ID);
query.setParameter("id", id);
result = (Service) query.getSingleResult();

这总是从数据库返回数据,但不是从Cache返回。

我如何测试 - >我在数据库中更改了一些列值,当我执行查询时,修改后的值即将到来。理想情况下,它应返回过时数据,因为缓存未刷新或无效。

修订版2:

如果我们尝试缓存命名查询,那么使用多租户感知持久性类将导致问题。怎么样?以下是我认为它的工作方式:

@Cache(
        type=CacheType.SOFT,
        size=6000,
        expiry=600000
)
@Multitenant
@TenantDiscriminatorColumn(...)
@NamedQueries({
    @NamedQuery(
            name=DBConstants.ALL_SERVICES, query="select s from Service s",
            hints={
                    @QueryHint(name = QueryHints.QUERY_RESULTS_CACHE, value = HintValues.TRUE),
                    @QueryHint(name = QueryHints.QUERY_RESULTS_CACHE_SIZE, value = "10")
            })
    })
})

@IdClass(ServicePK.class)
public class Service implements Serializable { ... }

创建EMF:

String tenantID = getTenantID();
properties.put(DBConstants.TENANT_ID_CONTEXT_PROPERTY, tenantID);
properties.put(DBConstants.LINK_SESSION_NAME, "session-" + tenantID);

if(emf == null)
    emf = Persistence.createEntityManagerFactory("<PERSISTENCE_UNIT_NAME>", properties);

创建EM:

em = emf.createEntityManager();

在这种情况下,我们的命名查询“ALL_SERVICES”将搜索所有服务,我们希望命名查询缓存根据该查询进行缓存。但是当我们执行这个查询时,EM会将tenantId附加到查询中,即

select s from Service s where s.tenantID = <VALUE>

它缓存在L1缓存的隔离缓存中,并且在您使用相同的EM实例之前可用。 创建新的EM实例时,它会在尝试调用DB上的查询之前检查该条目是否存在于L2缓存中。 L2缓存仅基于我们提到的查询而不是附加的tenantId。这会导致缓存命中未命中,并且呼叫始终进入后端。

现在......我该如何解决这个问题?我可以删除多租户注释并在查询中添加tenantId。我测试了它,它的工作非常好。

但是删除多租户注释会导致很多条件检查手动完成,尤其是当我们依赖其他持久性类时。

我需要一个更好的解决方案。谁能帮忙???

0 个答案:

没有答案