Search code examples
cachingehcachespring-cachecacheapi

@Cacheable annotation, using same value in a differents methods


I am trying to use the Spring @Cacheable annotation.

 @Cacheable(value="users")          
public List<User> findAll() {
    System.out.println("Looking for All users : ");
    return userRepository.findAll();
}

@Override
@Cacheable(value="users")  
public User findOne(String userId) {
    System.out.println("Looking for user : "+ userId);
    return userRepository.findById(userId).get();
}

When I execute the first methode List<User> I get :

  • 1st time : select all fields from DataBase
  • 2nd time : select all fields from Cache
  • 3rd time : select all fields from Cache

Which is good till now.

When I execute the second method findOne(String userId)I get the result from :

  • 1st time : select specific field from DataBase
  • 2nd time : select specific field from Cache
  • 3rd time : select specific field from Cache

Which is good again.

When I execute the first methode List<User> I get :

select all fields Data from Cache

Question : How the both methods (List<User> and findOne(String userId) had the same cache name but they return different result.


Solution

  • When you annotate your method with @Cacheable annotation, Spring will apply the caching behavior on it. The cache name is used to group the cache data in the same cache region. But to store the values in cache region, Spring will generate the cache key.

    By default the SimpleKeyGenerator is used to generate the key value in cache. SimpleKeyGenerator uses the method parameters to generate the cache key. The key value will be wrapped with the SimpleKey object.

    So, in your case it will do the following:

    1st call - no data in cache

    • List<User> findAll()

      1. no parameters
      2. key=SimpleKey.EMPTY
      3. store method result in cache using the key
    • User findOne(String userId)

      1. userId parameter
      2. key=new SimpleKey(userId)
      3. store method result in cache using the key

    As show above, although your cache name in @Cacheable is the same in both cases, the keys used to store method results are different. When you call again your methods:

    2nd call - data in cache

    • List<User> findAll()

      1. no parameters
      2. key=SimpleKey.EMPTY
      3. get the result from cache using the key
    • User findOne(String userId)

      1. userId parameter
      2. key=new SimpleKey(userId)
      3. get the result from cache using the key