Grails Cache and EHCache Plugin caches Controller methods but not Service methods

1.1k views Asked by At

I'm having trouble getting the Grails EHCache Plugin to cache service methods. Here is my setup:

Grails 2.4.2, JDK 1.7

BuildConfig.groovy compile ":cache-ehcache:1.0.4"

Config.groovy defines the following cache named "cache"

grails.cache.config = {
    cache {
        name 'cache'
        timeToLiveSeconds 60
    }
}

The following controller method properly caches. I have tested by setting a breakpoint in the method, and it only is hit the first time, until the cache expires.

@Cacheable('cache')
def index() {
    render "index-$params.id"
}

I can check the keys in the cache with:

grailsCacheManager.getCache('cache').getNativeCache().getKeys()

and see the value:

localhost:GET:/grails-cache-test/cache/index?id=34

So far so good.

The following service method exists:

@Cacheable('cache')
public method1(id) {
    "method1+$id"
}

I set a break point in here, and this method is always called, regardless of the @Cacheable annotation. I've tried setting the value and key annotation attributes manually, and no change. I test calling this method from a non-cached controller method, as well as directly from the console plugin. When I get the keys in the service method I see that there are no keys set.

I've looked through examples in the official documentation, code samples online, github, a book I have, everything looks good, so I'm not sure where the problem lies.

Any ideas on why this service method does not cache the value? Thanks!

UPDATE 1

I've been digging into the grails cache-1.1.8 plugin (as well as the associated cache-ehcache-1.0.4 plugin), and believe I've found something helpful. In PageFragmentCachingFilter.doFilter() there are calls to check the controller's annotations - but nothing to check the service. It appears that as a result, the service annotations are never honored. There is a lot of documentation that mentions service methods, so I don't know if there is something elsewhere that handles this, or if it's a less common use case compared to controller methods.

UPDATE 2

It appears that Controllers and Services are handled separately. In CacheAspectSupport.execute() there is a for() loop that will call cachePutRequest.apply(result.get());, which will actually add the entry to the cache. Unfortunately after the entry is added to the request, it is not immediately available to be retrieved. The underlying put() code is part of Spring Source, so at this point I'm not sure if it's a grails plugin issue or a Spring Source issue.

I have created a JIRA issue for this plugin GPCACHEEHCACHE-16

0

There are 0 answers