简体   繁体   English

操作 Hibernate 二级缓存

[英]Manipulating Hibernate 2nd Level Cache

I am using hibernate as my ORM solution, with EHCache as the Second Level (Read-Write) cache.我使用 hibernate 作为我的 ORM 解决方案,使用 EHCache 作为二级(读写)缓存。

My question is: Is it possible to access the Second Level cache directly?我的问题是:是否可以直接访问二级缓存?

I want to access this: http://www.hibernate.org/hib_docs/v3/api/org/hibernate/cache/ReadWriteCache.html我想访问这个: http://www.hibernate.org/hib_docs/v3/api/org/hibernate/cache/ReadWriteCache.html

How can I access the same ReadWriteCache that is being used by Hibernate?如何访问 Hibernate 使用的同一个 ReadWriteCache?

I have some direct/custom JDBC inserts that I am doing, and I want to add those objects to the 2nd level cache myself.我有一些我正在做的直接/自定义 JDBC 插入,我想自己将这些对象添加到二级缓存中。

I would call "afterInsert" on the EntityPersister that maps to your entity since Read/Write is an asynchronous concurrency strategy.我会在映射到您的实体的 EntityPersister 上调用“afterInsert”,因为读/写是一种异步并发策略。 I pieced this together after looking through the Hibernate 3.3 source.在查看了 Hibernate 3.3 源代码后,我将其拼凑在一起。 I am not 100% that this will work, but it looks good to me.我不是 100% 认为这会奏效,但它对我来说看起来不错。

EntityPersister persister = ((SessionFactoryImpl) session.getSessionFactory()).getEntityPersister("theNameOfYourEntity");

if (persister.hasCache() && 
    !persister.isCacheInvalidationRequired() && 
    session.getCacheMode().isPutEnabled()) {

    CacheKey ck = new CacheKey( 
                    theEntityToBeCached.getId(), 
                    persister.getIdentifierType(), 
                    persister.getRootEntityName(), 
                    session.getEntityMode(), 
                    session.getFactory() 
                );

    persister.getCacheAccessStrategy().afterInsert(ck, theEntityToBeCached, null);
}

-- --

/**
 * Called after an item has been inserted (after the transaction completes),
 * instead of calling release().
 * This method is used by "asynchronous" concurrency strategies.
 *
 * @param key The item key
 * @param value The item
 * @param version The item's version value
 * @return Were the contents of the cache actual changed by this operation?
 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
 */
public boolean afterInsert(Object key, Object value, Object version) throws CacheException;

Both hibernate and JPA now provide direct access to the underlying 2nd level cache: hibernate 和 JPA 现在都提供对底层二级缓存的直接访问:

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

I did this by creating my own cache provider.我通过创建自己的缓存提供程序来做到这一点。 I just overrode EhCacheProvider and used my own variable for the manager so I could return it in a static.我只是覆盖了 EhCacheProvider 并将我自己的变量用于管理器,因此我可以在 static 中返回它。 Once you get the CacheManager, you can call manager.getCache(class_name) to get a Cache for that entity type.获取 CacheManager 后,您可以调用 manager.getCache(class_name) 来获取该实体类型的 Cache。 Then you build a CacheKey using the primary key, the type, and the class name:然后使用主键、类型和 class 名称构建一个 CacheKey:

  CacheKey cacheKey = new CacheKey(key, type, class_name, EntityMode.POJO,
    (SessionFactoryImplementor)session.getSessionFactory());

The Cache is essentially a map so you can check to see if your object is in the cache, or iterate through the entities.缓存本质上是一个 map,因此您可以检查您的 object 是否在缓存中,或者遍历实体。

There might be a way to access the CacheProvider when you build the SessionFactory initially which would avoid the need to implement your own.当您最初构建 SessionFactory 时,可能有一种访问 CacheProvider 的方法,这将避免您自己实现的需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM