简体   繁体   中英

Grails - How to cache service method with grails.gorm.DetachedCriteria as parameter?

I have a service method as given below, that uses grails.gorm.DetachedCriteria as its parameter. Since this method is called frequently, i want to cache this method. But in this case, i get a hit on db, every time the method is called. I use grails "Cache plugin"

@Cacheable("totalCountCache")
public int count(DetachedCriteria detachedCriteria) throws Exception {
    return detachedCriteria.count();
}

If you don't specify a key, then the following default key generation strategy will be used:

public Object generate(Object target, Method method, Object… params) {

   if (params.length == 1) {
      return (params[0] == null ? 53 : params[0]);
   }

   if (params.length == 0) { return 0; }

   int hashCode = 17; 

   for (Object object : params) { 
      hashCode = 31 * hashCode + (object == null ? 53 : object.hashCode()); 
   } 
   return hashCode; 
} 

As your method only has a single parameter, the detachedCriteria itself will be used as the key, so the cache will be missed if:

  • you call this method with a unique detachedCriteria object (one that hasn't been encountered before)
  • you call this method with a detachedCriteria that has been encountered before, but the value cached for this object has expired

If this key generation strategy is not appropriate, you can override it by defining a spring bean named webCacheKeyGenerator that implements the grails.plugin.cache.web.filter.WebKeyGenerator interface (you can subclass DefaultWebKeyGenerator to simplify implementing this interface).

Focus of this question should be towards the parameter of function, DetachedCriteria . There is no way, (as far as i know) that a DetachedCriteria be used as a key.

Luckily for me, i had another object 'UserCriteria'(this is a custom object, that i created) which was used to create DetachedCriteria . so i updated the method so that it would accept my 'UserCriteria' object as parameter. Shown below

@Cacheable(value='userTotalCountCache', key='#userCriteria.toString()')
public int count(UserCriteria userCriteria) throws Exception {
    DetachedCriteria detachedCriteria = getDetachedCriteria(userCriteria);
    return detachedCriteria.count();
}

And it worked.

PS : For this to work, i had to override the toString() of the UserCriteria , since that is used as the key here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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