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

Woj*_*ski 8 java hibernate ehcache

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

假设我们有以下实体:

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

和查询:

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

查询缓存timeToLive设置为Dog timeToLive的大约3/4.这是场景(如果我作出了错误的假设,请纠正我):

  1. 第一次调用查询(假设缓存为空),执行它并将返回的Dog实例存储在二级缓存中.此外,Dog ID存储在查询缓存中.
  2. 第二次调用查询(Dog ID在查询缓存中,Dog对象在L2缓存中),一切正常.查询缓存返回id,并从L2获取Dogs.
  3. 当查询缓存过期(但L2缓存仍然有效)时,查询将重新运行并缓存Dog ID.
  4. 现在L2缓存为Dog对象过期,所有对象都从缓存中逐出.查询缓存仍然具有缓存的ID,因此hibernate 逐个获取Dog对象,这需要永远.

第三点是烦我.查询缓存无效并在数据库上重新运行,获取Dog对象,但Dog对象未在L2缓存中更新.看起来查询只更新了查询缓存中的dog ID,而不是L2缓存.

有没有办法强制查询更新L2缓存?也许这种情况要区别对待?

小智 1

我尝试过这个并在过去为我工作来清理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
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你