Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manipulating Hibernate 2nd Level Cache

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.

like image 841
mainstringargs Avatar asked Mar 31 '09 17:03

mainstringargs


2 Answers

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;
like image 95
Matt Sidesinger Avatar answered Nov 09 '22 14:11

Matt Sidesinger


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.

like image 24
Brian Deterling Avatar answered Nov 09 '22 13:11

Brian Deterling