2016-10-28 136 views
3

不久,我有一个启用2级缓存(只读策略)映射到查看DB(Oracle)的实体 - 的Ehcache。清除Hibernate的二级缓存

如果我手动在数据库更新一些列 - 高速缓存将不会被更新。

我没有找到任何方法来做到这一点。只有在更新将通过Hibernate实体完成。

我可以以某种方式实现此功能吗?

也许工作监控表(或视图)?或者也许有一些方法来通知Hibernate有关在具体表中的数据库更改。

感谢您的未来答案!

+0

只需添加一些函数刷新缓存的应用程序。然后在每次刷新时调用这个函数。没有这种功能的automagic版本 - 要么不手动更改数据库,要么执行应用程序中的功能以刷新“管理员”(您的)请求的缓存,还可以重新启动应用程序 - 它应该强制缓存被重新加载。 –

回答

2

Hibernate JavaDoc,您可以使用org.hibernate.Cache.evictAllRegions()

evictAllRegions()从缓存集中退出的所有数据。

使用会话和会话工厂:

Session session = sessionFactory.getCurrentSession(); 

if (session != null) { 
    session.clear(); // internal cache clear 
} 

Cache cache = sessionFactory.getCache(); 

if (cache != null) { 
    cache.evictAllRegions(); // Evict data from all query regions. 
} 

1)如果您需要更新只有一个实体(如果直接从数据库中你将只更新某些实体),而不是整个会话,你可以使用

evictEntityRegion(类entityClass)方法逐出从给定区域中的所有实体的数据(即

2)如果你有很多的实体,可以直接从数据库中您可以使用此方法驱逐从二级缓存中的所有实体进行更新(我们可以公开通过JMX或其他管理工具,这种方法管理员):

/** 
* Evicts all second level cache hibernate entites. This is generally only 
* needed when an external application modifies the game databaase. 
*/ 
public void evict2ndLevelCache() { 
    try { 
     Map<String, ClassMetadata> classesMetadata = sessionFactory.getAllClassMetadata(); 
     Cache cache = sessionFactory.getCache(); 
     for (String entityName : classesMetadata.keySet()) { 
      logger.info("Evicting Entity from 2nd level cache: " + entityName); 
      cache.evictEntityRegion(entityName); 
     } 
    } catch (Exception e) { 
     logger.logp(Level.SEVERE, "SessionController", "evict2ndLevelCache", "Error evicting 2nd level hibernate cache entities: ", e); 
    } 
} 

3)这里的另一个apporche描述here for postgresql+hibernate,我认为类似你能为甲骨文like this

+0

我不需要清除所有的缓存。我只需要更新与一个实体相关的缓存。 –

+0

那么你应该使用session.refresh(实体),因为Vimal写道 – Daniyar

+0

这意味着我必须在*检索数据之前调用refresh *我看不出任何意义使用缓存的情况下刷新调用 –

0

您可以使用session.refresh()方法重载这是目前在会议举行的对象。

阅读object loading for more detail

+0

每次我尝试使用我的实体 - 调用刷新方法? 如果我每次访问都会调用刷新,是否有任何意义使用缓存? –