我的问题:如何驱逐二级缓存查询?
到目前为止使用的技术:带有JPA 2.0和hibernate 3.2的Spring 3.2框架。
我在persistence.xml中定义了以下属性:
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
到目前为止,我们的代码中没有直接依赖Hibernate。
query.setHint("org.hibernate.cacheable", true);
回到问题:
我已经为复杂查询实现了二级查询缓存(6-7表连接和一些条件)。
好的是,所有这些表中的数据不太可能发生变化,因为相同的数据正在变得为每个用户触发,这是要缓存的完美查询。
但是,如果任何一个基础表中的数据得到更新,则需要逐出缓存。 JPA EntityManagerProvider提供了两种方法
emf.getCache().evictAll();
emf.getCache().evict();
我不能使用evictAll()
,因为我相信它会清除应用程序的所有缓存。
并且evict()
似乎仅用于从特定实体而非查询中删除缓存。
所以请为我提供最佳解决方案。
答案 0 :(得分:2)
当我使用包装数据库视图的实体时,我需要这样做。我以前从不缓存视图结果,直到我想出来。
这就是我现在所做的事情:
执行查询时,我会为两个缓存设置提示,并使用命名缓存区域。这个名字是任意的,可以是你想要的任何东西。
List allItems = em.createQuery("from EventStatus", EventStatus.class)
.setHint("org.hibernate.cacheable", true)
.setHint("org.hibernate.cacheRegion", "event-status")
.getResultList();
修改影响查询的任何实体后:
entityManagerFactory.unwrap(SessionFactory.class).getCache().evictQueryRegion("event-status");
我在配置中注册了一个全局侦听器,并在任何相关实体类发生更改后调用evictQueryRegion。
在任何批量删除(没有触发侦听器事件)之后,我手动逐出查询缓存区域。
当然,这是特定于Hibernate的。