繁体   English   中英

休眠缓存:缓存查询返回的对象是否存储在L2缓存中?

[英]Hibernate cache: Are objects returned by a cached query stored in L2 cache?

我们在项目中使用了hibernate4ehcache 我们主要处理不可变的对象,因此缓存是一项非常适合我们的应用程序的功能。 在尝试启用查询缓存时,我们遇到了以下问题:

假设我们具有以下实体:

@Entity 
@Table(name = "DOGS")
@Immutable 
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
class Dog {
  @Id @Column
  Long id;
  @Column
  String name;
}

和查询:

Criteria criteria = session.createCriteria(Dog.class);
criteria.add(Restrictions.in("id", ids));
criteria.setCacheable(true);

查询缓存timeToLive设置为Dog timeToLive的3/4。 这是场景(如果我做错了假设,请纠正我):

  1. 第一次调用查询(假设缓存为空)时,将执行查询并将返回的Dog实例存储在第二级缓存中。 另外,Dog ID也存储在查询缓存中。
  2. 第二次调用查询(Dog ID在查询缓存中,而Dog对象在L2缓存中),一切正常。 查询缓存返回ID,并且从L2中获取Dog。
  3. 当查询缓存过期(但L2缓存仍然有效)时,查询将重新运行并缓存Dog ID。
  4. 现在,Dog对象的L2缓存过期,并且所有对象都从缓存中逐出。 查询缓存仍然具有缓存的ID,因此休眠状态将Dog对象一个接一个地获取 ,这要花很长时间。

第三点困扰着我。 查询缓存无效,并在数据库上重新运行,以获取Dog对象,但是Dog对象在L2缓存中未更新。 看起来该查询仅更新了查询缓存中的狗ID,而不更新了L2缓存。

有没有一种方法可以强制查询也更新L2缓存? 也许这种情况将以不同的方式处理?

请参阅第二级缓存是针对您指定用于缓存的对象/ Pojo的。 但是查询缓存是为特定查询创建的。 因此看起来很自然,两者都不相关,并且当查询缓存更新时,二级缓存也不会更新。 这就是为什么两者都有不同的配置的原因。 您可以参考Hibernate Documentation此链接,或者此链接可以帮助您理解。

我尝试过这个并且过去为我工作以清理L2缓存

//clear the cache entity
sf.getCache().evictEntity(Dog.class,12345); //Entity with 12345 id

//or clear a collection 
sf.getCache().evictCollection("com.package.Dog.getCol",12345); //Collections
//Note: the collection contains the name of the fully qualified class.

//then, run the query

希望能帮助到你

就我而言,我禁用了休眠中的最小放置设置,然后每次SQL发出时,查询缓存将自动更新所有相关的第二级缓存。

我认为这是您的问题“强制查询也更新L2缓存”的解决方案(这也困扰了我很长时间.....)

<property name="hibernate.cache.use_minimal_puts" value="false"/>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM