我们有一个应用程序使用的休眠的第2级别的高速缓存,以避免数据库。

我想知道是否有一些简单的方法无效Java应用程序的休眠2级的高速缓存在外过程这样的作MySQL管理员直接连接到修改的数据库(update/insert/delete)。

我们使用 作为我们的第2级缓执行。

我们使用的混合@高速缓冲存储器(用法=CacheConcurrencyStrategy.READ_WRITE)和@高速缓冲存储器(用法=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE),并且我们没有乐观的并行控制使用时间戳在每个实体。

对它包含的方法来管理的第2级别的高速缓存:- 管理缓存

sessionFactory.evict(Cat.class, catId); //evict a particular Cat
sessionFactory.evict(Cat.class);  //evict all Cats
sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections

但是,因为我们注释个人与实体类@缓存,没有中心位置对于我们能够"可靠地"(例如没有手册的步骤)添加到名单。

// Easy to forget to update this to properly evict the class
public static final Class[] cachedEntityClasses = {Cat.class, Dog.class, Monkey.class}

public void clear2ndLevelCache() {
  SessionFactory sessionFactory = ...   //Retrieve SessionFactory

   for (Class entityClass : cachedEntityClasses) {
       sessionFactory.evict(entityClass);
   }
}

有没有现实的方式为休眠的第2级别的高速缓冲知道,一个实体,改变了在数据库,除非它查询的实体(其是什么样的高速缓冲保护你)。所以也许作为一种解决方案我们可以简单地调用的一些方法来力的二级缓驱逐的一切(再次因为缺乏锁定和并行控制你的风险,在进行交易从"阅读",或者更新陈旧的数据)。

有帮助吗?

解决方案

基于 ChssPly76 的评论,这里的方法可以将所有实体从二级缓存中逐出(我们可以将此方法暴露给管理员通过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();
        for (String entityName : classesMetadata.keySet()) {
            logger.info("Evicting Entity from 2nd level cache: " + entityName);
            sessionFactory.evictEntity(entityName);
        }
    } catch (Exception e) {
        logger.logp(Level.SEVERE, "SessionController", "evict2ndLevelCache", "Error evicting 2nd level hibernate cache entities: ", e);
    }
}

其他提示

SessionFactory 有很多 evict()方法正是为了这个目的:

sessionFactory.evict(MyEntity.class); // remove all MyEntity instances
sessionFactory.evict(MyEntity.class, new Long(1)); // remove a particular MyEntity instances

hibernate和JPA现在都提供对底层二级缓存的直接访问:

sessionFactory.getCache().evict(..);
entityManager.getCache().evict(..)

我正在搜索如何使所有Hibernate缓存失效,我找到了这个有用的代码段:

sessionFactory.getCache().evictQueryRegions();
sessionFactory.getCache().evictDefaultQueryRegion();
sessionFactory.getCache().evictCollectionRegions();
sessionFactory.getCache().evictEntityRegions();

希望对其他人有帮助。

您可以尝试这样做:

private EntityManager em;

public void clear2ndLevelHibernateCache() {
    Session s = (Session) em.getDelegate();
    SessionFactory sf = s.getSessionFactory();

    sf.getCache().evictQueryRegions();
    sf.getCache().evictDefaultQueryRegion();
    sf.getCache().evictCollectionRegions();
    sf.getCache().evictEntityRegions();

    return;
}

我希望它有所帮助。

有一件事的时候要考虑到使用分发高速缓存这QueryCache是本地,并驱逐了它的一个节点上,不驱逐从其他。另一个问题是-驱逐的实体区域而不驱逐的查询区域会导致N+1个选择中,当试图检索日期从查询高速缓冲存储器。好的读数关于这一主题 在这里,.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top