Avi
Avi

Reputation: 21760

@Cachable annotation does not work

We're using ehcache for caching purposes in our project.

import com.googlecode.ehcache.annotations.Cacheable;
// Other imports

@Component
public class Authenticator{
    @Cacheable(cacheName = "rest_client_authorized")
    public boolean isUserAuthorized(final String user, final String sessionId) {
        // Method code
    }
}

When entering the method there is no cache interceptor. The things we checked so far:

  1. We don't call this method from inside the class, but from the outside. So the problem is not inner calls that causes to bypass the proxy.
  2. We've added an interface for this class, and we changed the injections where this class is called to use the interface representation instead of the concrete class.

We have defined the cache manager in our application context this way:

   <ehcache:annotation-driven cache-manager="ehCacheManager" />         
   <bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
       <!-- use a share singleton CacheManager -->
       <property name="shared" value="true" />
   </bean>

The cache is defined like this:

        <cache name="rest_client_authorized"
            eternal="false"
            maxElementsInMemory="50"
            overflowToDisk="false" diskPersistent="false"
            timeToIdleSeconds="0" timeToLiveSeconds="600"
            memoryStoreEvictionPolicy="LRU" />

When we test the cache manager using Jconsole we can see that the cache *rest_auth_disabled* exists and empty.

Any ideas as to why this does not work will be most appreciated. Thanks!

Updates (aggregation from comments below):

==========================================**

That's a legacy code that worked fine with the class and definitions I've provided. The method I talk about here is new, but the rest of the class did work in past. So we're struggling to understand what has changed. We also tried already to replace the annotation to spring Cacheable, but still nothing :/ Maybe that depends on the code that calls this new method, which is from a different spring bean than what we used for the other methods. But I still can't find the issue.

Also tried to return Boolean instead of boolean following an answer below and it didn't work. We have a new lead which is probably related to the way we inject the bean (using @Autowire). Will update if that's indeed the case.

Upvotes: 3

Views: 6380

Answers (4)

Hanan Aharonof
Hanan Aharonof

Reputation: 46

This problem might have to do with the order Springs loads the beans. Try removing the @Autowire annotation from the Authenticator declartion, and do the autowiring manually. Something like:

/**
 * Class that uses Authenticator
 */

 public class X {

    // Don't use @autowire here
    public Authenticator athenticator;

    public void doSomething() {
         manuallyAutowire();
    }

    public void manuallyAutowire() {
         if(authenticator == null) {
    authenticator = ApplicationContextUtils.getApplicationContext().
                            getBean(authenticator.class);
    }
}

Where

@Component
public class ApplicationContextUtils implements ApplicationContextAware {

    private static ApplicationContext ctx;

    @Override
    public void setApplicationContext(final ApplicationContext appContext) 
                                          throws BeansException {
         ctx = appContext;

    }

    public static ApplicationContext getApplicationContext() {
        return ctx;
    }
}

Upvotes: 3

Dimitri Mestdagh
Dimitri Mestdagh

Reputation: 44665

As far as I know the Spring Ehcache annotations recommends that both parameter as return object should have an equals() and hashCode() method which primitive types lack.

I'm not sure if this framework is converting primitives to their wrapper variant (for example Integer or Boolean). Try returning the wrapper variant Boolean in stead of a primitive type and see if it works.

Another thing I'm not sure about is how (and if) it handles final parameters. If my first idea doesn't work, try removing the final keyword if possible and see if it works.

Upvotes: 1

Biju Kunjummen
Biju Kunjummen

Reputation: 49915

I think you are mixing up things here - You have used com.googlecode.ehcache.annotations.Cacheable, if you want Springs caching support it should actually be org.springframework.cache.annotation.Cacheable. Then the caching interceptors should work cleanly.

Upvotes: 1

cRx
cRx

Reputation: 39

The value of the parameter cacheName in @Cacheable should be the same with the value of the name attribute of <cache> declaration in your application-context

Upvotes: 1

Related Questions