Shahid Ghafoor
Shahid Ghafoor

Reputation: 3103

Spring MVC @Cacheable annotation on Generic Method

I am using spring MVC with Hibernate

Generic Method

    // getAllById
@SuppressWarnings("unchecked")
public <T> List<T> getAllById(Class<T> entityClass, long id)
        throws DataAccessException {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(entityClass)
            .add(Restrictions.eq("id", id));

    return criteria.list();
}

In controller

List<GenCurrencyModel> currencyList=pt.getAllById(GenCurrencyModel.class,1);

Question

How we can use @Cacheable("abc") annotation in Generic method and destroy the cache on demand using spring mvc + hibernate with generic DAO

According to the example in spring doc it specify annotation on simple method !

@Cacheable("books")
public Book findBook(ISBN isbn) {...}

I actually required, when Id pass to generic method ,it should first look up in cache, and I should also destroy cache on demand !

Upvotes: 3

Views: 2332

Answers (1)

a better oliver
a better oliver

Reputation: 26828

First of all think about the implications of using Generics for a moment:

  • You don't know which types you will use in the future. You don't know the cache names either for that matter.
  • You (may) have no type information, so there is no chance of choosing a specific cache.

The last point can be solved by always providing type information, like entityClass in your method.

Solution 1: One cache

Use one cache and generate a key based on the type. @Cacheable(value="myCache", key="#entityClass.name + #id")

Solution 2: Use @Caching

While you can use expressions for the key you can't use them for the cache names. @Caching allows you to use multiple @Cachable annotations, each with another cache name.

@Caching (
@Cacheable(value="books", key="#id", condition="#entityClass.name == 'Book'"),
@Cacheable(value="students", key="#id", condition="#entityClass.name == 'Student')
)

Solution 3: Write your own cache provider

This is not much of an effort to do. The Spring default cache provider is just a map after all. Your implementation could use different 'subcaches' for each type.

Clearing the cache is more difficult. The solutions 1 and 3 have only one cache. You cannot clear only 'books' but not 'students'. Solution 2 has that option but you have to provide all possible caches and types. You could use solution 3 and talk to the cache directly instead of using @CacheEvict.

Upvotes: 6

Related Questions