package org.infinispan.spring.provider.sample.service;
import org.infinispan.spring.provider.sample.dao.JdbcBookDao;
import org.infinispan.spring.provider.sample.entity.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @author <a href="mailto:olaf DOT bergner AT gmx DOT de">Olaf Bergner</a>
* @author Matej Cimbora (mcimbora@redhat.com)
*/
@Transactional
@Service
public class CachedBookServiceImpl implements CachedBookService {
@Autowired
private JdbcBookDao baseDao;
/**
* <p>
* Look up and return the {@code Book} identified by the supplied {@code bookId}. By annotating
* this method with {@code @Cacheable(value = "books", key = "#bookId")} we achieve the
* following:
* <ol>
* <li>
* {@code Book} instances returned from this method will be cached in a named
* {@link org.springframework.cache.Cache <code>Cache</code>} "books"</li>
* <li>
* The key used to cache {@code Book} instances will be the supplied {@code bookId}.</li>
* </ol>
* </p>
* <p>
* Note that it is <strong>important</strong> that we explicitly tell Spring to use {@code bookId}
* as the cache key. Otherwise, Spring would <strong>derive</strong> a cache key from the
* parameters passed in (in our case only {@code bookId}), a cache key we have no control over.
* This would get us into trouble when in {@link #updateBook(org.infinispan.spring.provider.sample.entity.Book)} we need a book's cache key to
* remove it from the cache. But we wouldn't know that cache key since we don't know Spring's key
* generation algorithm. Therefore, we consistently use {@code key = "#bookId"} or
* {@code key = "#book.id"} to tell Spring to <strong>always</strong> use a book's id as its
* cache key.
* </p>
*/
@Override
@Cacheable(value = "books", key = "#bookId")
public Book findBook(Integer bookId) {
return baseDao.findBook(bookId);
}
/**
* <p>
* Remove the book identified by the supplied {@code bookId} from database. By annotating this
* method with {@code @CacheEvict(value = "books", key = "#bookId")} we make sure that Spring
* will remove the book cache under key {@code bookId} (if any) from the
* {@link org.springframework.cache.Cache <code>Cache</code>} "books".
* </p>
*/
@Override
@CacheEvict(value = "books", key = "#bookId")
public void deleteBook(Integer bookId) {
baseDao.deleteBook(bookId);
}
/**
* <p>
* Store the supplied {@code bookToStore} in database. Since it is annotated with
* {@code @CacheEvict(value = "books", key = "#book.id", condition = "#book.id != null")}
* this method will tell Spring to remove any book cached under the key
* {@code book.getId()} from the {@link org.springframework.cache.Cache
* <code>Cache</code>} "books". This eviction will only be triggered if that id is not
* {@code null}.
* </p>
*/
@Override
@CacheEvict(value = "books", key = "#book.id", condition = "#book.id != null")
public Book updateBook(Book book) {
return baseDao.updateBook(book);
}
@Override
@CachePut(value = "books", key = "#book.id")
public Book createBook(Book book) {
return baseDao.createBook(book);
}
@Override
@Cacheable(value = "books", key = "#bookId", condition = "#bookId > 1")
public Book findBookCondition(Integer bookId) {
return baseDao.findBook(bookId);
}
@Override
@Cacheable(value = "books", key = "#bookId", unless = "#bookId > 1")
public Book findBookUnless(Integer bookId) {
return baseDao.findBook(bookId);
}
@Override
@Cacheable(value = "books", keyGenerator = "singleArgKeyGenerator")
public Book findBookCustomKeyGenerator(Integer bookId) {
return baseDao.findBook(bookId);
}
@Override
@Cacheable(value = "books", key = "#bookId", cacheResolver = "customCacheResolver")
public Book findBookCustomCacheResolver(Integer bookId) {
return baseDao.findBook(bookId);
}
@Override
@Cacheable(value = "backup", key = "#bookId")
public Book findBookBackup(Integer bookId) {
return baseDao.findBook(bookId);
}
@Override
@CachePut(value = "books", key = "#book.id", condition = "#book.title == 'Path to Infinispan Enlightenment'")
public Book createBookCondition(Book book) {
return baseDao.createBook(book);
}
@Override
@CachePut(value = "books", key = "#book.id", unless = "#book.isbn == '112-358-132'")
public Book createBookUnless(Book book) {
return baseDao.createBook(book);
}
@Override
@CachePut(value = "books", keyGenerator = "singleArgKeyGenerator")
public Book createBookCustomKeyGenerator(Book book) {
return baseDao.createBook(book);
}
@Override
@CachePut(value = "books", key = "#book.id", cacheResolver = "customCacheResolver")
public Book createBookCustomCacheResolver(Book book) {
return baseDao.createBook(book);
}
@Override
@CachePut(value = "books", key = "#book.id", cacheManager = "cacheManager")
public Book createBookCustomCacheManager(Book book) {
return baseDao.createBook(book);
}
@Override
@CacheEvict(value = "books", key = "#bookId", condition = "#bookId > 1")
public void deleteBookCondition(Integer bookId) {
baseDao.deleteBook(bookId);
}
@Override
@CacheEvict(value = "books", keyGenerator = "singleArgKeyGenerator")
public void deleteBookCustomKeyGenerator(Integer bookId) {
baseDao.deleteBook(bookId);
}
@Override
@CacheEvict(value = "books", key = "#bookId", cacheResolver = "customCacheResolver")
public void deleteBookCustomCacheResolver(Integer bookId) {
baseDao.deleteBook(bookId);
}
@Override
@CacheEvict(value = "books", key = "#bookId", allEntries = true)
public void deleteBookAllEntries(Integer bookId) {
baseDao.deleteBook(bookId);
}
@Override
@Caching(put = {@CachePut(value = "books", key = "#book.id"), @CachePut(value = "backup", key = "#book.id")})
public Book createBookCachingBackup(Book book) {
return baseDao.createBook(book);
}
@Override
@Caching(cacheable = {@Cacheable(value = "books", key = "#bookId"), @Cacheable(value = "backup", key = "#bookId")})
public Book findBookCachingBackup(Integer bookId) {
return baseDao.findBook(bookId);
}
@Override
@Cacheable(value = "books", cacheManager = "cacheManager")
public Book findBookCustomCacheManager(Integer bookId) {
return baseDao.findBook(bookId);
}
@Override
@Caching(evict = {@CacheEvict(value = "books"), @CacheEvict(value = "backup")})
public void deleteBookCachingBackup(Integer bookId) {
baseDao.deleteBook(bookId);
}
@Override
@CacheEvict(value = "books", cacheManager = "cacheManager")
public void deleteBookCustomCacheManager(Integer bookId) {
baseDao.deleteBook(bookId);
}
@Override
@CacheEvict(value = "books", beforeInvocation = true)
public void deleteBookBeforeInvocation(Integer bookId) {
throw new IllegalStateException("This method throws exception by default.");
}
}