简体   繁体   English

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

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

We're using hibernate4 and ehcache in our project. 我们在项目中使用了hibernate4ehcache We mostly work on immutable objects, so caching is a feature which fits nicely in our application. 我们主要处理不可变的对象,因此缓存是一项非常适合我们的应用程序的功能。 While trying to enable query cache, we ran into the following problem: 在尝试启用查询缓存时,我们遇到了以下问题:

Assuming we have the following entity: 假设我们具有以下实体:

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

and the query: 和查询:

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

The query cache timeToLive is set to about 3/4 of the Dog timeToLive. 查询缓存timeToLive设置为Dog timeToLive的3/4。 Here's the scenario (please correct me if I made a wrong assumption): 这是场景(如果我做错了假设,请纠正我):

  1. The first time the query is called (assuming the cache is empty), it is executed and the returned Dog instances are stored in the second level cache. 第一次调用查询(假设缓存为空)时,将执行查询并将返回的Dog实例存储在第二级缓存中。 Also, the Dog ids are stored in the query cache. 另外,Dog ID也存储在查询缓存中。
  2. The second time the query is called (the Dog ids are in the query cache and the Dog objects are in the L2 cache), everything works fine. 第二次调用查询(Dog ID在查询缓存中,而Dog对象在L2缓存中),一切正常。 The query cache returns the ids and the Dogs are fetched from L2. 查询缓存返回ID,并且从L2中获取Dog。
  3. When the query cache expires (but the L2 cache is still valid), the query re-runs and caches the Dog ids. 当查询缓存过期(但L2缓存仍然有效)时,查询将重新运行并缓存Dog ID。
  4. Now the L2 cache expires for the Dog object and all objects are evicted from cache. 现在,Dog对象的L2缓存过期,并且所有对象都从缓存中逐出。 The query cache still has the ids cached, so hibernate fetches the Dog objects one by one , which takes forever. 查询缓存仍然具有缓存的ID,因此休眠状态将Dog对象一个接一个地获取 ,这要花很长时间。

The 3rd point is bugging me. 第三点困扰着我。 The query cache got invalidated and re-ran on the database, fetching the Dog objects, but the Dog objects were not updated in the L2 cache. 查询缓存无效,并在数据库上重新运行,以获取Dog对象,但是Dog对象在L2缓存中未更新。 It looks like the query only updated the dog ids in the query cache, but not the L2 cache. 看起来该查询仅更新了查询缓存中的狗ID,而不更新了L2缓存。

Is there a way to force the query to update also the L2 cache? 有没有一种方法可以强制查询也更新L2缓存? Perhaps this scenario is to be handled differently? 也许这种情况将以不同的方式处理?

See Second Level cache is for Object/Pojos you specify for getting cached. 请参阅第二级缓存是针对您指定用于缓存的对象/ Pojo的。 But Query cache is created for specific queries. 但是查询缓存是为特定查询创建的。 So it seems natural that both are unrelated and second level cache will not get updated when your query cache gets updated. 因此看起来很自然,两者都不相关,并且当查询缓存更新时,二级缓存也不会更新。 That's why there is different configuration for both of them. 这就是为什么两者都有不同的配置的原因。 You can either refer Hibernate Documentation or this link or this link may help you understand things. 您可以参考Hibernate Documentation此链接,或者此链接可以帮助您理解。

I tried this and worked for me in the past to clean L2 cache 我尝试过这个并且过去为我工作以清理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

Hope it helps 希望能帮助到你

In my case, I disable the minimal put setting in hibernate and then the query cache will automatically update all the related second level cache each time when SQL issued. 就我而言,我禁用了休眠中的最小放置设置,然后每次SQL发出时,查询缓存将自动更新所有相关的第二级缓存。

I think this is the solution to your question "to force the query to update also the L2 cache" (This also bug me a long time.....) 我认为这是您的问题“强制查询也更新L2缓存”的解决方案(这也困扰了我很长时间.....)

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

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

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