views:

664

answers:

3

I am using hibernate as my ORM solution, with EHCache as the Second Level (Read-Write) cache.

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

How can I access the same ReadWriteCache that is being used by Hibernate?

I have some direct/custom JDBC inserts that I am doing, and I want to add those objects to the 2nd level cache myself.

+4  A: 

I would call "afterInsert" on the EntityPersister that maps to your entity since Read/Write is an asynchronous concurrency strategy. I pieced this together after looking through the Hibernate 3.3 source. I am not 100% that this will work, but it looks good to me.

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;
mattsidesinger
+1  A: 

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. Once you get the CacheManager, you can call manager.getCache(class_name) to get a Cache for that entity type. Then you build a CacheKey using the primary key, the type, and the class name:

  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.

There might be a way to access the CacheProvider when you build the SessionFactory initially which would avoid the need to implement your own.

Brian Deterling