Announcement Announcement Module
Collapse

Spring Modules forum decommissioned in favor of Spring Extensions

As the Spring Modules project has been replaced by the Spring Extensions (http://www.springsource.org/extensions) project, this forum has been decommissioned in favour of Spring Extensions one at:
http://forum.springsource.org/forumdisplay.php?f=44

Please see the Spring Extensions home page for a complete list of current projects in Java, .NET and ActionScript. You can also propose one if you want.

Cheers,
Costin Leau
SpringSource - http://www.SpringSource.com- Spring Training, Consulting, and Support - "From the Source"
http://twitter.com/costinl
See more
See less
Declarative Caching Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Declarative Caching

    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!

  • #2
    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


    • #3
      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


      • #4
        Originally posted by RShelley View Post
        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


        • #5
          Originally posted by RShelley View Post
          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.
          Last edited by imilina; Jan 2nd, 2008, 05:25 AM.

          Comment


          • #6
            Unfortunately, I'm hitting the same META exception barsk hit, and his solution (creating a "spring.schemas") doesn't seem to resolve it. I'll have to keep hacking at it.

            Let's hope someone takes the reigns here and gets this stuff back on track.

            Thanks for your feedback.
            Last edited by RShelley; Jan 3rd, 2008, 03:32 AM.

            Comment


            • #7
              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:

              Code:
              <beans xmlns="http://www.springframework.org/schema/beans"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
                     xsi:schemaLocation="
                     http://www.w3.org/1999/XSL/Transform http://www.w3.org/1999/XSL/Transform.xsd
                     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                     http://www.springmodules.org/schema/ehcache classpath:springmodules-ehcache.xsd
                     http://www.springmodules.org/schema/cache classpath:springmodules-cache.xsd">
              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


              • #8
                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.

                My caching app context is:
                Code:
                <beans xmlns="http://www.springframework.org/schema/beans"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
                       xsi:schemaLocation="
                       http://www.w3.org/1999/XSL/Transform http://www.w3.org/1999/XSL/Transform.xsd
                       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                       http://www.springmodules.org/schema/ehcache classpath:springmodules-ehcache.xsd
                       http://www.springmodules.org/schema/cache classpath:springmodules-cache.xsd">
                         
                	<!-- Cache manager -->
                	<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
                		<property name="configLocation" value="classpath:ehcache.xml" />
                	</bean>
                  
                	<!-- Cache provider -->
                	<bean id="cacheProvider" class="org.springmodules.cache.provider.ehcache.EhCacheFacade">
                		<property name="cacheManager" ref="cacheManager" />
                	</bean>
                  
                	<!-- Cache regions for annotated cache -->
                	<ehcache:annotations>
                	    <ehcache:caching id="productPageCacheModel" cacheName="PRODUCT_PAGE_CACHE" />
                	    <ehcache:flushing id="productPageFlushModel" cacheNames="PRODUCT_PAGE_CACHE" when="after" />
                	</ehcache:annotations>
                </beans>
                ehcache.xml is:
                Code:
                <ehcache>
                  <diskStore path="java.io.tmpdir/CIT_CACHE"/>
                  <cache name="PRODUCT_PAGE_CACHE"
                         maxElementsInMemory="300" 
                         eternal="false" 
                         timeToIdleSeconds="500"
                         timeToLiveSeconds="500" 
                         overflowToDisk="true" 
                         maxElementsOnDisk="1000" 
                         diskPersistent="true"/>
                  <defaultCache maxElementsInMemory="100" 
                                eternal="false"
                                timeToIdleSeconds="120" 
                                timeToLiveSeconds="120" 
                                overflowToDisk="true"
                                maxElementsOnDisk="1000"
                                diskPersistent="true"
                                diskExpiryThreadIntervalSeconds="120" 
                                memoryStoreEvictionPolicy="LRU" />
                </ehcache>
                And my classes have caching annotations as such:
                Code:
                  ...
                  @Cacheable(modelId = "productPageCacheModel")
                  private Map getCatalogPage(int siteId, int page, int folderId, int resultsPerPage){
                  ...
                So my "modelId" matches the "id" in my caching application context, and the application context's "cacheName" matches the "name" attribute in my ehcache.xml.

                Logging from Spring-Modules and ehCache is empty. And just to make sure, we don't need to have a "Cacheable" interface implemented on the class, right?

                Any ideas?
                Last edited by RShelley; Jan 3rd, 2008, 04:52 PM.

                Comment


                • #9
                  I can tell that Ehcache is being configured properly. The debug log of Ehcache reads:

                  Code:
                  578  [http-8084-3] (ConfigurationFactory.java:139) DEBUG net.sf.ehcache.config.ConfigurationFactory  - Configuring ehcache from InputStream
                  585  [http-8084-3] (DiskStoreConfiguration.java:71) DEBUG net.sf.ehcache.config.DiskStoreConfiguration  - Disk Store Path: /tmp
                  590  [http-8084-3] (ConfigurationHelper.java:212) DEBUG net.sf.ehcache.config.ConfigurationHelper  - No CacheManagerEventListenerFactory class specified. Skipping...
                  591  [http-8084-3] (ConfigurationHelper.java:186) DEBUG net.sf.ehcache.config.ConfigurationHelper  - No CachePeerListenerFactoryConfiguration specified. Not configuring a CacheManagerPeerListener.
                  592  [http-8084-3] (ConfigurationHelper.java:161) DEBUG net.sf.ehcache.config.ConfigurationHelper  - No CachePeerProviderFactoryConfiguration specified. Not configuring a CacheManagerPeerProvider.
                  611  [http-8084-3] (ConfigurationHelper.java:136) DEBUG net.sf.ehcache.config.ConfigurationHelper  - No BootstrapCacheLoaderFactory class specified. Skipping...
                  613  [http-8084-3] (ConfigurationHelper.java:136) DEBUG net.sf.ehcache.config.ConfigurationHelper  - No BootstrapCacheLoaderFactory class specified. Skipping...
                  644  [http-8084-3] (DiskStore.java:887) DEBUG net.sf.ehcache.store.DiskStore  - Index file /tmp/PRODUCT_PAGE_CACHE.index created successfully
                  647  [http-8084-3] (DiskStore.java:195) DEBUG net.sf.ehcache.store.DiskStore  - Index file dirty or empty. Deleting data file PRODUCT_PAGE_CACHE.data
                  655  [http-8084-3] (MemoryStore.java:73) DEBUG net.sf.ehcache.store.MemoryStore  - Initialized net.sf.ehcache.store.LruMemoryStore for PRODUCT_PAGE_CACHE
                  678  [http-8084-3] (LruMemoryStore.java:71) DEBUG net.sf.ehcache.store.LruMemoryStore  - PRODUCT_PAGE_CACHE Cache: Using SpoolingLinkedHashMap implementation
                  680  [http-8084-3] (Cache.java:510) DEBUG net.sf.ehcache.Cache  - Initialised cache: PRODUCT_PAGE_CACHE
                  However, it seems as though Spring-Modules isn't picking up on the @Cacheable annotation, because I see nothing in the Caching logs when a request is made to a method with the @Cacheable annotation.

                  Comment


                  • #10
                    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


                    • #11
                      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.

                      Comment


                      • #12
                        Issue with annotated caching

                        my application context is the following...

                        Code:
                        <?xml version="1.0" encoding="UTF-8"?>
                        <beans xmlns="http://www.springframework.org/schema/beans"
                            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                            xmlns:context="http://www.springframework.org/schema/context"
                            xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
                            xsi:schemaLocation="http://www.springframework.org/schema/beans 
                                                http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
                                                http://www.springframework.org/schema/context 
                                                http://www.springframework.org/schema/context/spring-context-2.5.xsd
                                                http://www.springmodules.org/schema/ehcache
                                                http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd">
                        
                        	<context:component-scan base-package="com" />
                        	
                        	<ehcache:config configLocation="classpath:/ehcache.xml" serializableFactory="XSTREAM" />
                         	
                            <ehcache:annotations>
                               <ehcache:caching id="testDaoCacheModel" cacheName="test1Cache" />
                               <ehcache:caching id="testNonDaoCacheModel" cacheName="test2Cache" />
                               <ehcache:flushing id="flushNonDaoCacheModel" cacheNames="test1Cache" />
                            </ehcache:annotations> 
                        	
                            <!-- View Resolvers -->
                            <bean id="bundledViewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
                                <property name="basename" value="views"/>
                                <property name="order" value="0"/>
                            </bean>
                            
                        </beans>
                        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


                        • #13
                          Hi

                          Originally posted by joshr View Post
                          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?

                          Regards

                          Johan Hammar

                          Comment


                          • #14
                            I haven't found any so far, I am guessing this issue should be raised as a bug.
                            Last edited by joshr; Jan 19th, 2009, 07:17 PM.

                            Comment


                            • #15
                              Originally posted by joshr View Post
                              I haven't found any so far, I am guessing this issue should be raised as a bug. I'll see if I can come up with a simple test case today...
                              Im having same problem like yours and this is my thread: please take a look and give me some advises

                              http://forum.springframework.org/showthread.php?t=66148

                              Thanks in advance

                              Comment

                              Working...
                              X