Java Hibernate缓存:缓存查询返回的对象是否存储在二级缓存中?
我们在项目中使用了hibernate4和ehcache。我们主要处理不可变的对象,因此缓存是一个非常适合我们的应用程序的特性。尝试启用查询缓存时,我们遇到以下问题: 假设我们拥有以下实体:Java Hibernate缓存:缓存查询返回的对象是否存储在二级缓存中?,java,hibernate,ehcache,Java,Hibernate,Ehcache,我们在项目中使用了hibernate4和ehcache。我们主要处理不可变的对象,因此缓存是一个非常适合我们的应用程序的特性。尝试启用查询缓存时,我们遇到以下问题: 假设我们拥有以下实体: @Entity @Table(name = "DOGS") @Immutable @Cache(usage = CacheConcurrencyStrategy.READ_ONLY) class Dog { @Id @Column Long id; @Column String name;
@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。以下是场景(如果我的假设错误,请纠正我):
有没有办法强制查询同时更新二级缓存?也许这种情况需要以不同的方式处理?我曾尝试过这种方法,并在过去为我清理二级缓存
//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
希望它能有所帮助查看二级缓存是针对您指定用于获取缓存的对象/POJO的。但查询缓存是为特定查询创建的。所以,当查询缓存更新时,二级缓存将不会得到更新,这似乎很自然。这就是为什么它们都有不同的配置。您可以参考或帮助您理解事情。在我的例子中,我在hibernate中禁用了最小put设置,然后每次发出SQL时,查询缓存都会自动更新所有相关的二级缓存 我认为这就是你的问题“强制查询同时更新二级缓存”的解决方案(这也让我很长时间感到困扰……)
您可以启用读/写缓存模式,以便EHCache在更新时对其进行处理。该实体是只读的,因此没有帮助。您建议我何时清理缓存?如果我在每次请求之前都清除它,那么拥有一个缓存就毫无意义了。我在计划的事件中清除了缓存(由于项目事实)。因此,我们会不时清理缓存(计划时间由系统团队确定),因此这实际上取决于您的项目数据库大小和使用情况。如果没有准确的数据,就不可能猜测问题的关键是我不想添加任何退出缓存的启发式算法,因为我不能100%确定所描述的情况不会发生。我知道这是两个不同的缓存,但是查询缓存使用域缓存按id检索对象,对吗?这导致了所描述的问题,到目前为止我还没有找到任何解决方案。朋友,你需要接受这个设计。这不是一个问题,这是这样设计的。我希望你访问我提供的链接。我会让你知道,如果我遇到的东西,可能会帮助你解决这个问题。我知道这些链接,我已经搜索了很多,以找到这个问题的答案:)然而,如果这是工作的设计,那么设计真的很糟糕。假设缓存的查询返回1000个ID,那么1000个选择将被发送到数据库。:-)这是这样的:0
<property name="hibernate.cache.use_minimal_puts" value="false"/>