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."); } }