This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.

Declarative Caching

Dec 30th, 2007, 12:33 AM

Has anyone successfully implemented Declarative Caching with Spring Modules? I've checked out a few of the threads here regarding DC, but they seem incomplete (or not clearly explained). I also reviewed the documentation on the Spring Modules site and they seem to conflict (or are not up to date) with someone of the posts here. I'd like to see some example code of using DC with annotations. It'd be nice if Spring Modules provided actual code examples like the main Spring project. The issue with the schema definitions still seems to plague the project. Any help would be greatly appreciated! Thanks!

Hi,
I posted most of my config in this thread. All of my code works as expected, although it is quite different from the code in the documentation. Some people reports problems with schema definitions, but I had problems only with eclipse not recognizing some of the caching xsd tags.

Regards,
Igor.

Comment

I did read this post, however, I didn't quite get the "complete example" from it. Was your second post in the thread the complete example? I suppose it's the difference between your post and the documentation that makes it seem somehow incomplete.

All the configuration you need are the two bean definitions, single annotation definition, and then the actual annotations themselves? You need nothing else? The documentation mentions an "implements Cacheable" for the class containing cacheable annotations, is that not necessary? You don't need a CacheProxyFactoryBean? No CacheKeyGenerator? AnnotationCachingAttributeSource? MetadataCachingInterceptor? CachingAttributeSourceAdvisor? None of them?

It would be really helpful if the Spring Modules developers actually created a sample project implementing declarative caching for reference.

Comment

All the configuration you need are the two bean definitions, single annotation definition, and then the actual annotations themselves? You need nothing else? The documentation mentions an "implements Cacheable" for the class containing cacheable annotations, is that not necessary? You don't need a CacheProxyFactoryBean? No CacheKeyGenerator? AnnotationCachingAttributeSource? MetadataCachingInterceptor? CachingAttributeSourceAdvisor? None of them?

That's right Remember, we are talking about quite abstract xsd config here, so Spring probably creates most of those beans internally. If you had to configure caching using "old style" beans definitions you'd probably need more verbose config.

The official docs are confusing. I read a chapter from "Spring in action" 2nd ed. which had all this caching business explained better. This is also the source of my config code.

Comment

It would be really helpful if the Spring Modules developers actually created a sample project implementing declarative caching for reference.

Agreed. And I would really like to know what is the status of this project, anyway? The jira roadmap is a bit strange, with the next version (0.9) already being eight months behind the schedule... Most of the questions here about caching are left unanswered, and I haven't seen anybody talking about using declarative caching in production. For this reason I'm a little unsure of using it too.

Comment

Ok, well, my setup just had to be different. For reference, I'm in Netbeans 6.0, and while the application context files for ehcache don't resolve internal to Netbeans, I have been able to get them to be resolved by Tomcat. I haven't validated whether caching is working yet, but for what it's worth, here's how I was able to work around the META tag issue:

1) Copy springmodules-ehcache.xsd and springmodules-cache.xsd from the Spring-Modules JAR and place them into my /WEB-INF/classes folder. Then in my ehcache Application Context file, I defined the schemaLocation as:

Note the "classpath:..." section. Since /WEB-INF/classes is in the classpath for each web-app, it resolves. It does not, however, resolve for Netbeans. I was able to get it to resolve in Netbeans by using "../classes/springmodules...xsd" (without "classpath:") to fully qualify it, however, this does not work in Tomcat. I tried several variations on the "classpath:..." theme to try to get it to resolve in both (such as "classpath:/org/springmodules/.../springmodules...xsd"), however, that did not seem to work either. Since it doesn't HAVE to be qualified to build, it works ok, but you don't get code-completion in the editor.

Comment

Well, it builds and runs fine, but it doesn't appear that caching is working. In my case, I'm caching the return of a SOAP call, however, in my logs I can see that the SOAP request is being executed instead of returning a cached response.

Comment

So I went back and reread one of your posts, imilina, and it makes perfect sense now:

The reason is simple. Spring actually creates a proxy of your bean when you use declarative cache. So, if you call a method of your cacheable bean from some other bean, you actually call a method of a proxy bean (not your target bean) that will apply caching mechanism and call the actual method if neccessary.

But, if your cacheable bean's method call its own method, there is no intercepting mechanism that can apply cache here - this is just a normal method call. So this whole "declarative cache" idea can be applied only for interface/public methods that are exposed for other beans to use.

I was trying to Cache the return of a private method. I'll spin it off and stick it in a separate object and try again.

Comment

So after playing with Declarative Caching, the first thing that I notice is that the Flushing Model flushes the entire cache. I see in the EhCacheFacade.java file that there is a method for "onRemoveFromCache" which removes a single object from the cache, however, I don't see an interface for doing so. It seems all-or-nothing. I'm sure there's a way to get it to remove one object at a time and not just flush the entire cache, but I haven't come across it yet.

and this works perfect for annotating my methods for caching and flushing when I load the context files at the same time.

However, I am experiencing an issue when my context files are loaded at different times...

example:
If I use spring-security and I load my security context in the web.xml file with a context-param tag, the above code is loaded in the applicationContext-servlet.xml file by spring. If I have any methods that are annotated in my spring-security context file, caching doesn't work for the methods loaded through my spring-security context file. I was wondering if there is a switch or a configuration option I need to set so that all of my annotated methods will be cached no matter when they are loaded?

The only solution I have found so far is to find all of classes that I need to use for caching, along with my caching configuration and make sure they are loaded the same time my security context file is loaded... But I would imagine that it would be easier for people using this library to not have to worry about when to load their classes?

Comment

example:
If I use spring-security and I load my security context in the web.xml file with a context-param tag, the above code is loaded in the applicationContext-servlet.xml file by spring. If I have any methods that are annotated in my spring-security context file, caching doesn't work for the methods loaded through my spring-security context file. I was wondering if there is a switch or a configuration option I need to set so that all of my annotated methods will be cached no matter when they are loaded?

The only solution I have found so far is to find all of classes that I need to use for caching, along with my caching configuration and make sure they are loaded the same time my security context file is loaded... But I would imagine that it would be easier for people using this library to not have to worry about when to load their classes?

We're also affected by this problem in our project. Is there another solution for this or do we have to load all caching in the security context?