-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Handling new entity creation with an eternal query cache
PostPosted: Wed Aug 25, 2010 10:39 pm 
Newbie

Joined: Wed Aug 25, 2010 9:14 pm
Posts: 5
I have the following scenario:
1. query cache enabled, query cache region is eternal (never evicts). My query cache is massive (entire db is cached in L2 for performance reasons).
2. queries used in the query cache make strict use of natural identifiers to avoid query cache eviction upon update/delete/insert
( see this excellent article for background on this: http://tech.puredanger.com/2009/07/10/h ... ery-cache/ )
3. A new entity is created which matches the criteria of the cached query. Upon creation, the query cache is not evicted (because of item 2). As a result, the query cache returns stale results exclusive of the newly created entity.

The obvious solution to fix my stale query cache is to simply evict upon entity creation. However, doing so will present a huge performance issue because I deliberately cache the entire contents of the database (using a distributed terracotta/ehcache L2 cache) and want to avoid cache eviction at all costs. The query cache is delivering me a 10x performance increase, too good to ignore.

I want the query cache to be smart enough to automatically update cached query results for natural id queries when a new entity is created. This seems to me quite a (somewhat) legitimate expectation when dealing with a natural ID query where it is possible for a new entity to be assessed from the criteria and added to a cached query result without having to repeat the query at the database.

I am blurring the intended use of natural ID queries and it should not be possible for the result of a natural ID query to ever change (unless the entity is deleted), even with the creation of a new entity. If natural ids are strictly intended to uniquely identify an entity then fair enough. I'm am pushing the boundaries by using natural id based queries to define a query result that cannot change other than the deletion or addition of a new entity (since natural id fields are immutable). Natural key based queries avoid eviction and I'm exploiting this to realise big performance gains.

I have modified the store() method in my DAO used upon entity creation to manually access the query cache and update the cached result.
This appears to work for me and I am thinking about generalizing this functionality in my DAO framework and possibly suggesting this as an improvement to hibernate core. The difficulty is that it is not known at dao.store() which query caches require updating. A handle to the criteria/hql for each cached query is required to resolve the QueryKey, and the query cache region name, so that the query cache can be accessed.

Code:

   //SNIP

  //The following is added to my dao.store() method after the creation of a new entity 'newEntity'.
  //The code here exists in the context of a hibernate session (inside a Spring JPA template execute() callback)

   //resolve the cached query criteria without executing it - my criteria query has been refactored so I can get the criteria via a local private method 'getQueryCachedCriteria'
   CriteriaImpl criteriaImpl = (CriteriaImpl) getQueryCachedCriteria(session,newEntity.getNaturalIdentifierField());
                  
   //resolve runtime attributes of the criteria necessary to access the query cache - i have a helper class to perform the necessary magic
   Type[] resultTypes = helper.getResultTypes(sessionFactoryImpl,criteriaImpl,entityClass.getName());
                  
   Set querySpaces = helper.getQuerySpaces(sessionFactoryImpl,criteriaImpl, entityClass.getName());
                  
   String sqlString = helper.getSqlString(sessionFactoryImpl, criteriaImpl, entityClass.getName());
                  
   QueryParameters queryParameters = helper.getQueryParameters(sessionFactoryImpl, criteriaImpl,entityClass.getName());
                  
   Set filterKeys = FilterKey.createFilterKeys((SessionImplementor)session).getLoadQueryInfluencers().getEnabledFilters(),session.getEntityMode());

   QueryKey key = QueryKey.generateQueryKey(sqlString, queryParameters, filterKeys, session);
   
   //get a handle on the query cache
   QueryCache queryCache = sessionFactoryImpl.getQueryCache(criteriaImpl.getCacheRegion());
   
   //get the current result from the cache
   List result = queryCache.get(key, resultTypes, true, querySpaces, session);
                  
   if(result==null){
   //The query has not been cached so we don't need to do anything here.
   //The next time the query runs it will be resolved from the db and added to the cache
   //including the new entry.
   return;
   }
                  
   //update the result,
   if(!result.contains(newEntity)){
   result.add(newEntity);
                     
   //then put the result back in the cache (update)
   if ( session.getCacheMode().isPutEnabled() ) {
      boolean put = queryCache.put( key,resultTypes, result, queryParameters.isNaturalKeyLookup(), session );
   }
   }

//SNIP   

//here is my natural id criteria:
   
   public Criteria getQueryCachedCriteria(
         org.hibernate.Session session,
         Entity entity){
      
      Criteria criteria = session.createCriteria(persistantClass, "e");
      
      NaturalIdentifier naturalIdentifier = Restrictions.naturalId()
         .set("e.naturalIdentifierField", entity.getSomeField());

      criteria.add(naturalIdentifier)
         .setCacheable(true)
         .setCacheRegion("query.query1");
      
      return criteria;
   }              


I am wondering whether anybody else has the same or similar requirement and has any advice.

Thanks!

Simon


Top
 Profile  
 
 Post subject: Re: Handling new entity creation with an eternal query cache
PostPosted: Tue Aug 31, 2010 1:49 am 
Newbie

Joined: Wed Aug 25, 2010 9:14 pm
Posts: 5
This is a similar posting:
viewtopic.php?f=1&t=985000&start=0


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.