Spring 3.1 M1: Cache Abstraction |
|

One of the major features added in Spring Framework 3.1 M1 is the generic cache abstraction for transparently applying caching to Spring applications. Just like the transaction support, the caching abstraction allows consistent use of various caching solutions with minimal impact on the code.
Purpose
Caches are in general used to improve application performance by transparently serving frequently accessed data in a faster fashion such as serving data from local memory rather than from the network. Many of you have already used caching, whether knowingly or not: most ORM/JPA frameworks provide dedicated caching functionality (also known as the 2nd-level cache). Spring 3.1 M1 however introduces a generic cache mechanism that can be applied to any Java class, method or library: one can use it in conjunction with an existing caching infrastructure, to add caching to APIs without such support (for example JDBC) or simply to improve the performance of a slow, time-consuming and resource-hungry method.
Meet @Cacheable, @CacheEvict and SpEL
Let us see what it takes to cache an arbitrary method:
@Cacheable("books")
public Book findBook(ISBN isbn) {...}
By marking the method with the @Cacheable annotation, we tell the container that the findBook method is backed by the cache entry books. That is each time the method is called, a cache lookup is performed using as key the method parameters (in this case the isbn argument). If a value is found, it will be returned and the method execution skipped. However, if the key is not found, the method is executed as usual and its result stored in the cache so the next time the method is invoked, the result can be returned without actually executing the (expensive or slow) method.
In practice not all methods have only one argument or, worse yet, the parameters are not suitable as cache keys – take for example a variation of the method above:
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
In such cases, one can use Spring 3 Spring Expression Language or SpEL to cherry pick the proper arguments, navigate the object tree
// use property 'rawNumber' on isbn argument as key @Cacheable(value="book", key="#isbn.rawNumber") public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
or compute the key on the fly, even call arbitrary methods without having to write any code:
// get the key by calling someType#hash(isbn) @Cacheable(value="book", key="T(someType).hash(#isbn)") public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
Additionally, one can specify when or if the caching should occur: whether the cache should be inspected or completely disregarded and the method executed normally. It's up to the developer to decide what the criteria is: can be anything from the key size or type to the time of day or result of arbitrary methods: SpEL supports it all:
// cache only names shorter then 32 chars @Cacheable(value="book", condition="#name.length < 32") public Book findBook(String name)
// do not cache on weekends @Cacheable(value="book", condition="!T(TimeUtils).isWeekend()") public Book findBook(String name)
The cache abstraction also supports eviction of cache entries or of an entire cache through the @CacheEvict annotation. To evict a cache once it becomes invalid (for example because the cached data has been updated) one can use the following:
// evict all cache entries @CacheEvict(value = "books", allEntries=true) public void loadBooks(InputStream batch)
Once the annotations are in place, one can simply "enable" the caching functionality with one line (or three if you count the schema declaration):
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<cache:annotation-driven />
...
</beans>
Just like the rest of the annotation-driven element, the cache one uses defaults in its simplest form but can be used to pick between proxy and byte-code weaving of cached classes or to wire in the desired cache implementation.
Declaring a cache implementation
So far, we discussed the declarative aspect of the caching abstraction: how to add and remove data from the cache based on your POJOs. But what are the backing cache implementations that one can use?
Out of the box, Spring provides integration with ehcache and JDK ConcurrentHashMap great for small, non-distributed environments or testing:
<!-- generic cache manager -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentCacheFactoryBean" p:name="default"/>
<bean class="org.springframework.cache.concurrent.ConcurrentCacheFactoryBean" p:name="books"/>
</set>
</property>
</bean>
What about [xx] library – when will it be supported ?
For the moment we do not plan to support other caching libraries inside Spring Framework simply because of the sheer number of options out there, the dependency impact (many are bigger in size than the cache abstraction), and the maintenance and licensing issues. To plug-in a custom cache provider, we encourage developers to look at the caching SPI package and its two interfaces: CacheManager and Cache. Besides the implementations available out of the box, one can look at the GemFire implementation, scheduled for the next major release version of Spring GemFire.
How does the caching abstraction compare to other caches (e.g. JPA 2nd-level cache) ?
In general, the two caching mechanisms can happily coexist as long as the developer pays attention to any domain overlap. Taking the example of the JPA 2nd-level cache, one can used it for data access through JPA while using Spring caching for the web-tier or remote service calls. One can go a step further by reusing the backed cache between the two mechanisms if that applies.
Summary
I hope you enjoyed this quick introductory entry to the new caching feature in Spring 3.1. For more information, please see the relevant reference documentation chapter and the SPI javadoc. And do let us know what you think – we are interested in your feedback! You can reach us through the forum, blog post comments, our issue tracker or yours truly on Twitter.
Similar Posts
- Transactions, Caching and AOP: understanding proxy usage in Spring
- XPath Support in Spring Web Services
- Spring Framework 3.1 M2 released
- Spring Framework 3.1 goes GA
- Spring Framework 3.1 RC1 released





Rahul says:
Added on February 23rd, 2011 at 6:22 amGr8 article to start with Spring 3.1 features. Should definitely give it a go…
Ricardo Espergue says:
Added on February 23rd, 2011 at 9:08 amThis is definitely cool feature, this will simplify what we currently have in one of our applications.The Expression Language allows extra flexibility !!!
Just wondering about how many element's can we cache, let's say I have a service that could return 10k records, is it safe to use the ehcache implementation and cache these 10k elements?
Costin Leau (blog author) says:
Added on February 23rd, 2011 at 9:18 am@Ricardo
It's really up to the underlying cache, its capabilities and eviction policies. The JDK concurrent map will keep growing as long as there's free memory to use. More advanced implementations, depending on the configuration, will either evict items from the cache (to the disk for example) or the distribute the load to other peers. I can't comment on ehcache since I haven't used it that much but GemFire for example supports all the scenario above.
gonfi says:
Added on February 23rd, 2011 at 9:26 am"Spring 3.1 M1 however introduces a generic cache mechanism that can be applied to any Java class, method or library"
– static methods?
– methods called from within the class itself?
Costin Leau (blog author) says:
Added on February 23rd, 2011 at 9:39 am@gonfi
It depends on what type of weaving one picks. Bytecode weaving (based on AspectJ) gives you ultimate functionality (including the methods you mentioned before). The proxy-based approach (i.e. cglib and JDK proxies) work only provide 'regular' method interception, that is caching if the (non-static) method is invoked from another object.
The two options are described at length in the AOP chapter from the Spring Framework documentation:
http://static.springsource.org/spring/docs/3.1.0.M1/spring-framework-reference/html/aop.html#aop-choosing
Jaap says:
Added on February 23rd, 2011 at 10:27 amI miss the ability to be able to generate a collection of keys to be deleted. Are there plans to add something like this to the cache abstraction?
Juan Carlos González González says:
Added on February 23rd, 2011 at 11:06 amHi,
Nice feature. I've downloaded Spring 3.1 and tested this feature. However I've got one question.
Suppose I have the typical CRUD service
@Cacheable("employee")
public Employee findEmployee(String id)
@CacheEvict(value="employee", key="employee.id")
public void save(Employee employee)
@Cacheable("employees")
public Collection findAll()
.
.
.
My question is how can I simultaneously CacheEvict two different caches?. The save method should CacheEvict both caches: employee and employees. I know that I can use something like this:
@CacheEvict(value={"employee", "employees"}, allEntries=true)
public void save(Employee employee)
but this approach would clear completely both caches. So, is there anyway to CacheEvict the saved object in employee cache and, simultaneously, CacheEvict completely employees cache?
Best regards,
Juan Carlos
Costin Leau (blog author) says:
Added on February 23rd, 2011 at 11:09 am@Jaap
Feel free to raise an issue for this. @Cacheable and @CacheEvict currently complement and map each other nicely. From the top of my head, to support collections the key needs to be unwrapped (from raw collection to collection of keys) which adds some corner cases/assumptions in what the collection contains and how it is computed.
Costin Leau (blog author) says:
Added on February 23rd, 2011 at 11:19 am@Juan Carlos
Unfortunately Java doesn't allow the same annotation to be specified multiple times so if you have multiple eviction policies, so for now you could use a meta-annotation (see the reference documentation) to define your own type and declare that along a traditional @CacheEvict:
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) @CacheEvict("employees", allEntries="true") public @interface EvictEmployees { }@EvictEmployees @CacheEvict("employee") public void save(Employee employee)We can add a grouping annotation (such as @CacheEvictions) to group multiple @CacheEvict annotations in one place – we had something like this in the POC. Can you please raise an issue for this?
Thanks!
John says:
Added on February 23rd, 2011 at 11:43 amWill there be a support to memcached?
Costin Leau (blog author) says:
Added on February 23rd, 2011 at 11:53 am@John
Not inside Spring Framework. If there is enough demand for it (such as votes on the issue tracker) we might add it in the Spring Data project which deals with NoSQL stores: http://www.springframework.org/spring-data
Tobias says:
Added on February 24th, 2011 at 9:03 amHi Costin,
when playing around with this nice feature, I found out that I have to use a # in front of the parametername if I want to use a parameter as a key:
@Cacheable(value = "employee", key="#id")
public Employee findEmployee(String id)
Is there a bug in the documentation or in the code?
Regards,
Tobias
P.S.: Forum-Post: http://forum.springsource.org/showthread.php?t=103372
Costin Leau (blog author) says:
Added on February 24th, 2011 at 9:51 am@Tobias
Nice catch – indeed the arguments require '#' in front. I have updated the blog to fix this.
Cheers,
bestguy says:
Added on February 24th, 2011 at 1:52 pmHi,
Few of us were wondering if/how Java config can be used in lieu of
http://forum.springsource.org/showthread.php?p=347733
Thanks
oliver says:
Added on March 2nd, 2011 at 4:25 pmHi Costin,
We solved a performance problem using java.lang.ref.SoftReference. By this we use as much memory as possible and we can avoid an OutOfMemoryError.
What about to provide a cache implementation backed by SoftRefrence?
Regards,
Oliver
Costin Leau (blog author) says:
Added on March 2nd, 2011 at 5:24 pm@Oliver
Currently we're focusing on the abstraction part only not so much on an actual implementation (in fact we don't provide any). Many cache implementations provide the feature you mentioned – and if you want to use your own you can easily add it in.
Costin Leau (blog author) says:
Added on March 2nd, 2011 at 5:27 pm@bestguy
Sorry, just now saw your post – replied to it. Basically we'll provide an equivalent in the next milestones (we might get around it even for M2).
bestguy says:
Added on March 2nd, 2011 at 7:59 pmExcellent, thanks for the update Costin
Chris Faulkner says:
Added on March 3rd, 2011 at 8:33 amThis looks quite useful but is there anyway of marking methods as cacheable in XML config rather than as annotations ?
We use org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource to mark our transactional methods as such. In some areas, I'd still like to use XML rather than annotations and this would definitely be one of them.
Costin Leau (blog author) says:
Added on March 3rd, 2011 at 9:02 am@Chris
We plan to address that in a future milestone so you can use both XML and annotations.
Dave Curry says:
Added on March 5th, 2011 at 1:30 amThis is really cool. I'm using it with EhCache. However, I notice that if a cache entry is evicted by the expiration of timeToLiveSeconds (rather than @CacheEvict), @Cacheable returns null rather than proceeding with the method call. Is this by design?
Costin Leau (blog author) says:
Added on March 5th, 2011 at 12:37 pm@Dave Can you please raise an issue with an example or test case? We don't store any information per se and always use the backing cache. So in this case it sounds like Ehcache considers the key to be cached and the value associated with it to be null – or, our Ehcache integration fails to properly check or return the cache.
Dave Curry says:
Added on March 6th, 2011 at 3:48 am@Costin I just entered SPR-8023 with an example.
https://jira.springsource.org/browse/SPR-8023
Costin Leau (blog author) says:
Added on March 6th, 2011 at 3:50 am@Dave Thanks – we'll look into it as soon as possible.
Costin Leau (blog author) says:
Added on March 6th, 2011 at 7:00 am@Dave – the issue has been fixed in the latest trunk/snapshot. Let me know how it goes for you. Cheers!
Dave Curry says:
Added on March 7th, 2011 at 3:36 pm@Costin – It works a treat! Thanks for the quick turnaround!!!
Ravi says:
Added on March 8th, 2011 at 10:28 amThis is really a piece of cake for me. I will try implementing this in my next Spring project. Thanks for the blog.
Neil Laurance says:
Added on March 14th, 2011 at 10:18 amThanks for this clear and concise description of Cacheable abstration
Bozhidar Bozhanov says:
Added on March 24th, 2011 at 2:29 amIt would be nice if the documentations includes a hint to use the null-safe operator in custom keys – key = "#foo?.bar". Or is there a better way to handle a possibly null argument there?
David says:
Added on March 24th, 2011 at 8:42 amHi All,
I can remember writing a generic cache provider using aspectJ a few months ago. one of the key features of that implementation was to ensure it was compartible with various JSR107 cache implementations on the market.
The question is, is the spring implementation jsr107 compliant?
David
Costin Leau (blog author) says:
Added on March 25th, 2011 at 6:27 pm@Bozhidar
It's really up to the SpEL expression used. Can you please raise an issue to add in some lines about this?
Thanks!
@David
JSR107 is not finalized – in fact there are multiple versions flying around in various products. For this reason JSR107 was not considered but it can be implemented though we don't plan to address this ourselves considering the spec is inactive (and practically dead since it's over 10 years old without any final jar or doc in place).
gwa says:
Added on June 9th, 2011 at 2:01 amHello,
I have to work with some cachemanager in my application.
Is it a way to use @Cacheable annotation to use a specific cachemanager for some method, another cachemanager for other method ?
Costin Leau (blog author) says:
Added on June 9th, 2011 at 2:42 amNo. However you can use a "chained" cache manager that can contain multiple managers and delegate the cache lookup to each of them. Since @Cacheable allows the cache "region" to be specified you can use that as a discriminator to cache the values under a certain manager (that contains only those regions).
Joshua White says:
Added on June 28th, 2011 at 3:06 pmCostin,
I would like to have a discussion about some of the changes in the cache abstraction between the M1 and M2 releases. Is there a forum specifically for the 3.1 workstream or the cache abstraction?
Thanks,
Joshua
Paul Middelkoop says:
Added on June 29th, 2011 at 2:53 amI use the cache abstraction with Spring JPA Data. Works great except that I cannot use parameter names in SpEL expressions on methods I override from JpaRepository. I get this exception: org.springframework.expression.spel.SpelEvaluationException: EL1007E:(pos 8): Field or property 'name' cannot be found on null
When I use parameter numbers there is no problem. Is this a bug?
My code:
public interface DealerRepository extends JpaRepository {
@Override
@Transactional
@CacheEvict(value = "dealers", key = "#entity.name")
Dealer save(Dealer entity);
}
Harshi says:
Added on July 1st, 2011 at 7:48 pmVery good article. It would be nice to post example where methods called from within the class itself?
And how it works with Declarative transactions?
Zhan says:
Added on July 25th, 2011 at 3:26 amHello,
thank you for this article. I wanted to have a method inside my Dao which will update a user entity:
User updateUser(User newUser). For the cache, it should evict the old user entity and put the new one instead. Each user has a unique id, which is used as a key for cache. Is there a way to achieve this using these annotations?
Thank you in advance!
Regards, Zhan.
Anup Sheth says:
Added on July 27th, 2011 at 10:21 amCurrently @Cacheable is throwing NullPointer exception if one or more parameter(s) are null.
@Cacheable
public List getSomething(String a, Integer b, Long c)
for
getSomething("", new Integer("1"), new Long("1")) it works but for
getSomething("", new Integer("1"), null)
getSomething("", null, new Long("1")) or any null parameter it throws NullPointer exception.
I think this case should be handled gracefully i.e. ignoring those null parameters in key generation.
I can generate my own key using spel but the implementation of the @Cacheable is not mature as I would have expected.
Correct me if i am worng.
Thanks,
Anup
Costin Leau (blog author) says:
Added on July 27th, 2011 at 12:13 pm@anup
This has been fixed in the trunk (it might be part of M2 already – I'm not near a computer to verify).
If you're already using M2, try one of the snapshots.
And in the future, please use the issue tracker for reporting bugs.
Thanks!
Rajagopal Yendluri says:
Added on August 11th, 2011 at 3:26 amHi,
We are planning to implement the Spring Cache Abstraction.
Here is piece of code that we are using now for caching.
public class MyCacheAPI{
public void putInCache(String key, Object value) {
admin.putInCache(key, value); // admin is OSCache's GeneralCacheAdministrator.
}
…..
}
Key is userId fileName Value is : FileStream.
If i need to implement the Spring Cache Abstraction, how do i change the above piece of code.
Mario Guerrero says:
Added on August 14th, 2011 at 6:31 pmSome days ago i made an example but using ehcahe. I would like use gigaspaces as a Spring Cache provider.
May you help me to setup gigaspaces as Spring Cache provider
Thanks.
Mario Guerrero says:
Added on August 14th, 2011 at 6:55 pmHi. I am working with spring framework and Gigaspaces (7.1.4). Some days ago i read about "Spring 3.1 M1: Cache Abstraction".
http://blog.springsource.com/2011/02/23/spring-3-1-m1-caching/
http://www.parleys.com/#st=5&id=2185
http://www.javacodegeeks.com/2011/02/spring-31-cache-abstraction-tutorial.html
http://static.springsource.org/spring/docs/3.1.0.M1/spring-framework-reference/html/cache.html
I made an example but using ehcahe. I would like use gigaspaces as a Spring Cache provider.
May you help me to setup gigaspaces as Spring Cache provider
Thanks.
Mario Guerrero
guedim@gmail.com
sean says:
Added on August 18th, 2011 at 10:44 amhttp://static.springsource.org/spring/docs/3.1.0.M1/spring-framework-reference/html/cache.html in this document the class name is error "org.springframework.cache.ehcache.EhcacheCacheManager".the right class name is "org.springframework.cache.ehcache.EhCacheCacheManager" 。 attention: EhcacheCacheManager -> EhCacheCacheManager
David Karlsen says:
Added on August 21st, 2011 at 12:08 pmWill this work be aligned with the JSR work here:
https://jsr107.ci.cloudbees.com/job/jsr107api/ws/target/apidocs/index.html
https://github.com/jsr107/jsr107spec
Costin Leau (blog author) says:
Added on August 21st, 2011 at 1:54 pm@Mario
Take a look at the existing implementations and consider adapting one to Gigaspaces – it should be straight forward.
@sean
Thanks!
@David
Of course
Stemlaur says:
Added on September 7th, 2011 at 2:07 amHi, I have a question regarding the caching with spring : is that possible to configure Spring to automaticly rollback the cache modifications when JDBC rollback occurs…
I'm talking here of consistency between the cache and the DB.
Thank you in advance.
Costin Leau (blog author) says:
Added on September 7th, 2011 at 3:00 am@Stemlaur
You don't have to – rollbacks usually occur if your method throws an exception. If the same method is marked as @Cacheable, the cache update happens after the method gets successfully executed, which because of the exception won't happen.
Stemlaur says:
Added on September 7th, 2011 at 3:21 amThank you @Cleau for the reply,
I agree that 'rollbacks usually occur if your method throws an exception', but on a global transaction the exception is not necessarily thrown by the @Cacheable method itself… but anyway the JDBC changes will be rollbacked and the method (because the exception is thrown somewhere else) gets successfully executed.
In that situation, are we certain that the cache process won't occur ?
Costin Leau (blog author) says:
Added on September 7th, 2011 at 3:59 am@Cacheable works at method level so if the method returns successfully there is no indication that something went wrong. Assuming your part of a global transaction so the rollback occurs after you've invoked the method – for such cases you have several options (from the top of my head):
1. see whether the cache provider supports transactions – if it does then you simply tie that to the ongoing tx.
2. if it doesn't, you need to "add" the rollback behaviour. You can check (through a TransactionSynchronization for example, if you're using Spring's TX) whether something went wrong and remove data from the cache in case of a rollback. You have different variations here such as updating the cache to the old value (that was used for the rollback) rather then just deleting it.
3. You can move the cacheable annotation all the way to the top level basically using the same scope as your tx. This way you know whether the method was successfully executed or not.
Paul N says:
Added on September 14th, 2011 at 5:30 amIS this caching methodology for Spring managed beans only or can it be done for domain objects as well.
We are currently using aspectj for the latter but it would be nice if Spring supported this too.
Jose says:
Added on September 19th, 2011 at 5:41 amHi there,
Costin, I'd really appreciate if you could have a look at what I've posted on spring's forum.
It's something related to a lack of functionality in @CacheEvict annotation.
http://forum.springsource.org/showthread.php?114837-CacheEvict-incomplete-functionality&p=380326#post380326
Thanks!
Jose
jbbarquero (Javier) says:
Added on September 27th, 2011 at 3:16 amHello:
I've tried the code with an existing Roo project (1.1.5) & Spring 3.1.0.M2 and I've found these problems:
- It seems that the class org.springframework.cache.concurrent.ConcurrentCacheFactoryBean no longer exists. As I could see at http://vimeo.com/28721724, I replaced it in the cacheManager definition by org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean
- When I executed the tests, I found this error:
java.lang.IllegalStateException: Post-processor tried to replace bean instance of type [com.malsolo.cache.domain.Currency] with (proxy) object of type [$Proxy36] – not supported for aspect-configured classes!
brandon says:
Added on September 28th, 2011 at 11:59 amI implemented my own CacheManager and all of the other interfaces in the org.springframework.cache package (http://static.springsource.org/spring/docs/3.1.0.M2/javadoc-api/org/springframework/cache/package-frame.html). I've enabled the caching within my app (), but it appears to still be using the DefaultKeyGenerator, even though I've written my own. Where do I tell Spring to use my own custom key generator? I don't see any options in the XML namespace nor in the CacheManager interface.
Costin Leau (blog author) says:
Added on September 28th, 2011 at 1:04 pm@brandon
Can you please raise an issue? We could improve the configuration for the KeyGenerator in the namespace.
Thanks
brandon says:
Added on September 28th, 2011 at 2:13 pmJIRA 8730 has been created to address this issue. https://jira.springsource.org/browse/SPR-8730
brandon says:
Added on September 30th, 2011 at 8:14 amI've created another JIRA 8733 to address an issue I encountered while attempting to use the @Cachable
along with @EnableTransactionManagement. My testing of the caching works when the @EnableTransctionManagement is commented out of my @Configuration class. However, when this annotation is enabled, the application context fails to start up. See JIRA 8733 for more details.
https://jira.springsource.org/browse/SPR-8733
Suprio says:
Added on October 1st, 2011 at 1:56 pmWhere do I add the TTL for the following type of cache?
Is it in the @Cacheable annotation?
Bill says:
Added on October 12th, 2011 at 12:23 pmIts nice to see this functionality in the main Spring project. The cache implementation that was part of Spring Modules made integrating a cache with a service very simple.
Matt says:
Added on October 21st, 2011 at 1:17 pmGreat feature and blog article!
Is there a Java configuration (@Configuration) alternative to <cache:annotation-driven /> similar to @EnableTransactionManagement planned for this feature?
Christian Nuesa says:
Added on October 31st, 2011 at 6:16 pmCostin, you post is simple to follow but has left me hanging on one issue. Whenever I annotate my service with @Cacheable/evict, the service is not loaded in Spring and therefore not injected. Is there anything that I missed? I do not get any other exception but java.lang.IllegalStateException: Failed to load ApplicationContext, which is because my service is not injected.
roy kachouh says:
Added on November 3rd, 2011 at 1:45 pmAwesome! It looks like you guys took a page from http://code.google.com/p/ehcache-spring-annotations/wiki/UsingCacheable
zheng says:
Added on November 4th, 2011 at 2:25 pmHow would one implement it for Memcached provider, as it does not have a "named cache" concept?
abc says:
Added on November 15th, 2011 at 2:12 pmmy comments never get published….
abc says:
Added on November 15th, 2011 at 2:16 pmOk, Now that I can write here… I found an issue.
Spring 3.1 has correct xsd at http://www.springframework.org/schema/cache/spring-cache-3.1.xsd but the one bundled with the
jar file at org.springframework.context.support-3.1.0.RC1.jar\org\springframework\cache\config\ was not updated with key-generator attribute. Hence the context loading fails saying key-generator is not allowed as part of
Current work around is to delete the xsd from the jar file.
abc says:
Added on November 15th, 2011 at 2:24 pmWhat I meant was:: Hence the context loading fails saying key-generator is not allowed as part of
cache:annotation-driven key-generator="myKeyGenerator"
Leen Toelen says:
Added on December 5th, 2011 at 4:02 amIf you are interested in memcached support, I have written a simple implementation at https://github.com/toelen/spymemcached-springcache
It uses spymemcached internally.
Silviu says:
Added on December 8th, 2011 at 6:46 amHi Costin,
I'm going for bytecode (based on AspectJ) weawing so that cache mechanism can be applied to a method called from within the class itself.
It is worth saying that first I played with proxy-based approach and everything was working (method is invoked from another object in that case).
As soon as I moved to aspectJ no caching takes place.
I see there is someone else facing the same issue. http://forum.springsource.org/showthread.php?117368-New-Spring-Caching-Not-Working-With-AspectJ-LTW
Any sugestion?
Thank you
Silviu says:
Added on December 8th, 2011 at 7:17 amHi Costin,
I'm using cache abstraction mechansim : I've set up bytecode (based on AspectJ) weawing so that cache mechanism can be applied to methods called from within the class itself.
It is worth saying that first I was using proxy-based approach : everything was working fine (for methods that are invoked from another object.)
As soon as I switched to AspectJ,no caching takes place (not even for the methods that are invoked from another object)
I see the same problem has been reported http://forum.springsource.org/showthread.php?117368-New-Spring-Caching-Not-Working-With-AspectJ-LTW
Any sugestion?
Thank you.
Costin Leau (blog author) says:
Added on December 8th, 2011 at 8:26 am@Silviu
Let's continue the discussion on the forum – thanks for raising this up.
alecsboga says:
Added on January 3rd, 2012 at 11:39 amHi Costin,
Nice feature this cache abstraction!
I'd like to monitor the caching (ehcache implementation) using JMX, ehcache has support for it but unfortunately it will expect his CacheManager and not "org.springframework.cache.ehcache.EhCacheCacheManager", is there any support yet within spring cache abstraction for JMX monitoring?
Thanks,
Alex
Costin Leau (blog author) says:
Added on January 3rd, 2012 at 12:40 pm@alecsboga
No, there's no JMX support in the abstraction since the native implementation provides a lot more information and as you pointed out, it's already there.
As for your question (please try the forum next time), you can get a hold of the native API through Cache#getNativeCache()
From there you can get a hold of the CacheManager (we'll probably expose that on the EhCacheManager as well to make it simpler).
alecsboga says:
Added on January 3rd, 2012 at 3:19 pmTank you! (multzam fain
)
Chirag says:
Added on January 5th, 2012 at 1:47 pmI certainly like the caching abstraction that is available with Spring. I have been using Google's caching abstraction with Ehcache. I like to new flexibility of using any arbitrary keys.
However, I have an ongoing requirement dealing with the flexibility of readBehind implementations which are hard with such caching abstraction. I have been thinking about creating custom version of @Cacheable annotation that allows the flexibility of specifying to load the caches in the background so that cache evictions don't penalize the client requests.
Let me know if there is already any facility in Spring that I can leverage.
numan says:
Added on February 1st, 2012 at 9:52 pmHas this been integrated in grails 2.0? The current spring-cache plugin has a dependency on ehcache but which might be a dealbreaker for people who want to use Redis or Memcached.
gopi says:
Added on March 10th, 2012 at 4:17 amHi,
I configured my spring version 3.1.0.RELEASE version and getting ClassNotFoundException for org.springframework.cache.concurrent.ConcurrentCacheFactoryBean,
as per the "spring-context-3.1.0.RELEASE" jar the concurrent package shows as
org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean
is RELEASE version higher than M1 version?
Mihnea Pretorian says:
Added on March 12th, 2012 at 8:45 amDoes Spring cache abstraction support write-through/write-behind cache strategies?
Costin Leau (blog author) says:
Added on March 19th, 2012 at 11:40 pm@Chirag
Cache warm-ups tend to be implementation specific and outside the scope of the cache abstraction. I would recommend using the native API during start-up or a certain entry point – note that advanced caches provide such functionality (aka read-ahead) so when an entry is first request and needs to be read, a bulk of data is added to the cache.
@numan
Not yet as far as I know, but I believe work is underway. It's best to raise this (potentially through an issue) on the Grails site.
@gopi
RELEASE is higher then M(x) – do upgrade.
@Mihai
That's up to the backing cache implementation not the cache abstraction. Some do support such functionality (that needs to be configured) some don't.
Mihnea Pretorian says:
Added on March 20th, 2012 at 4:25 am@Costin, about the write-through feature.
I was hoping to find in Spring cache abstraction an annotation similar with CachePut from JSR107. See this blog: http://gregluck.com/blog/archives/category/jcache/. Is any other way to achieve that with Spring?
Regards, Mihnea (2011/devoxx/ro)
Costin Leau (blog author) says:
Added on March 20th, 2012 at 4:36 am@Mihnea
See @CachePut in cacheable package [1] – this causes a cache update to occur as oppose to @Cacheable which checks the presence of the cache.
Note that this is unrelated to write-through – the cache implementation can decide to decide the backing store right then or may postpone the update (write-behind).
[1] http://l.leau.ro/GB5ghR
Mihnea Pretorian says:
Added on March 20th, 2012 at 1:48 pm@Costin, thank you. CachePut annotation in Spring is what I was searching for.
Odyss says:
Added on March 21st, 2012 at 2:02 pmHi,
Some cache name's are "book" and some are "bookS". It is correct ?
Thks
ragnor says:
Added on August 1st, 2012 at 10:31 amFew months ago I reactivated Simple Spring Memcached (SSM) project: http://code.google.com/p/simple-spring-memcached/. In version 3.0.0 it provides integration with Spring Cache so memcached can be used as a cache back-end. SSM is not an another java memcached client, it uses spymemcached or xmemcached.
Andrii Neverov says:
Added on September 18th, 2012 at 4:07 amHi,
Is there any support planned for self-refreshing caches similar to http://ehcache-spring-annotations.googlecode.com/svn/site/current/apidocs/index.html? And if so – when?
Thanks
Andrii Neverov says:
Added on September 18th, 2012 at 4:19 amThe correct link is:
http://ehcache-spring-annotations.googlecode.com/svn/site/current/apidocs/com/googlecode/ehcache/annotations/RefreshingSelfPopulatingCache.html
Lorand says:
Added on February 7th, 2013 at 12:50 amHi, I have a question related to cache reset.
@Cacheable(value = "permissions", key = "#email")
public Set getPermissions(String email) {
return userDAO.getPermissions(email);
}
@CacheEvict(value = "permissions", allEntries=true )
public void resetPremissionsCache(){
}
public void addPermission(String email, String domain, String meetingKey, ACTION action) {
System.out.println("AuthUserServiceImpl.addPermission()");
ShiroPermission shiroPermission = new ShiroPermission();
userDAO.addPermission(email, shiroPermission);
resetPremissionsCache();
}
public void removePermission(String email, String domain, String meetingKey, ACTION action) {
System.out.println("AuthUserServiceImpl.removePermission()");
userDAO.removePermission(email, shiroPermission);
resetPremissionsCache();
}
I already tried all of possibilities, can anybody say how can I reset the cache on add & remove, simply is not working.