我们在项目中使用hibernate4和ehcache。我们主要处理不可变对象,因此缓存是一个非常适合我们应用程序的功能。在尝试启用查询缓存时,我们遇到了以下问题:
假设我们有以下实体:
@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 左右。这是场景(如果我做出错误的假设,请纠正我):
- 第一次调用查询时(假设缓存为空),它被执行,返回的 Dog 实例存储在二级缓存中。此外,Dog id 存储在查询缓存中。
- 第二次调用查询(Dog id 在查询缓存中,Dog 对象在 L2 缓存中),一切正常。查询缓存返回 ids 并且从 L2 获取 Dogs。
- 当查询缓存过期(但二级缓存仍然有效)时,查询重新运行并缓存 Dog id。
- 现在,Dog 对象的 L2 缓存到期,所有对象都从缓存中逐出。查询缓存仍然缓存了 id,因此 hibernate 会一个一个地获取 Dog 对象,这需要很长时间。
第三点困扰着我。查询缓存失效并在数据库上重新运行,获取 Dog 对象,但 Dog 对象未在 L2 缓存中更新。看起来查询只更新了查询缓存中的狗 ID,而不是 L2 缓存。
有没有办法强制查询也更新 L2 缓存?也许这种情况要以不同的方式处理?