Page 1 of 3 123 LastLast
Results 1 to 10 of 27

Thread: Caching only required getter methods??

  1. #1

    Default Caching only required getter methods??

    Hi,

    I'm using Declarative Cahcing Using Spring and EHCache.

    Requirements is to cache the particular private and public methods of a class.
    But the following technique is to cache the all getter methods of a proxied object.

    <bean id="testProxyBean"
    class="org.springmodules.cache.interceptor.proxy.C acheProxyFactoryBean">
    <property name="cacheProviderFacade" ref="cacheProviderFacade" />
    <property name="target" ref="test" />
    <property name="cachingModels">
    <props>
    <prop key="get*">
    ............
    ............

    HOW can i cache only required getter methods using this mechanism?

    Can anybody throw ones ideas?
    Your help is highly appreciated.

    Thanks in advance,
    Ganesh

  2. #2
    Join Date
    Dec 2005
    Location
    Croatia
    Posts
    192

    Default

    Use annotations, if you work with Java5 or higher. Complete configuration sample:

    Code:
    <!-- 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="petsCacheModel" cacheName="petsCache"/>
    	<ehcache:flushing id="petsFlushModel" cacheNames="petsCache" when="after"/>
    </ehcache:annotations>
    
    
    In your class you annotate a methods like this:
    @Cacheable(modelId = "petsCacheModel")
    public Pet getById(Integer id) {
    }
    
    @CacheFlush(modelId = "petsFlushModel")
    public void savePet(Pet pet) {
    }
    Could you please post your impressions of declarative cache here after you implement it in your app? There seem to be very few posts about this, and I also wonder how does it perform in production.

    Regards,
    Igor.

  3. #3

    Default

    Hi Igor,

    Thanks for your reply.

    You wrote

    Code:
    In your class you annotate a methods like this:
    @Cacheable(modelId = "petsCacheModel")
    public Pet getById(Integer id) {
    }
    
    @CacheFlush(modelId = "petsFlushModel")
    public void savePet(Pet pet) {
    }
    Which class you are talking about?
    For example, If it is application class which has business methods to be cached, you might know, we should not touch it.
    It it is an AspcectJ class and any other please let me your views.
    I'm not that much experienced on spring-caching.
    Please elaborate on this. It' better to give a complete code.

    i'm supposed to use CacheProxyFactoryBean strategy.

    This is my configuration file:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 
    	"http://www.springframework.org/dtd/spring-beans.dtd">
    
    <beans>
    
    	<!-- The created cache manager is an instance of net.sf.ehcache.CacheManager -->
    	<bean id="cacheManager"
    		class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    	</bean>
    	<!-- Enabling the Auto Serialization unless an object implements java.io.Serializable(i)-->
    	<bean id="serializableFactory"
    		class="org.springmodules.cache.serializable.XStreamSerializableFactory" />
    	<!-- EHCache can be used as CACHE PROVIDER through the FACADE -->
    	<bean id="cacheProviderFacade"
    		class="org.springmodules.cache.provider.ehcache.EhCacheFacade">
    		<property name="cacheManager" ref="cacheManager" />
    		<!--<property name="serializableFactory" ref="serializableFactory" />-->
    		<!--<property name="failQuietlyEnabled" value="true" />-->
    	</bean>
    	<!-- Enabling @AspectJ Support  -->
    	<bean
    		class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" />
    	<!-- LoggingHandler is an aspect class for logging -->
    	<bean id="loggingHandler"
    		class="com.cit.ecommerce.spring.logging.LoggingHandler" />
    	<!-- AdaptorExceptionHandler is an aspect class for Exception Handling -->
    	<bean id="adaptorExceptionHandler"
    		class="com.cit.ecommerce.spring.exceptions.AdaptorExceptionHandler" />
    	<bean id="securityServiceAdaptor"
    		class="com.cit.ecommerce.adaptor.registration.SecurityServiceAdaptorImpl_UnitTestStub" />
    	<!--CacheProxyFactoryBean applies caching services to securityServiceAdaptor bean -->
    	<bean id="proxyBean"
    		class="org.springmodules.cache.interceptor.proxy.CacheProxyFactoryBean">
    		<property name="cacheProviderFacade" ref="cacheProviderFacade" />
    		<property name="target" ref="securityServiceAdaptor" />
    		<property name="cachingModels">
    			<props>
    				<prop key="get*">
    					cacheName=CITeCOMMERCEPORTAL_CACHE;
    				</prop>
    			</props>
    		</property>
    		<property name="flushingModels">
    			<props>
    				<prop key="update*">
    					cacheNames=CITeCOMMERCEPORTAL_CACHE;
    				</prop>
    			</props>
    		</property>
    	</bean>
    	<!-- Injecting spring management to XMLFileLoader -->
    	<bean id="contractService" class="ContractServiceAdaptor">
    		<property name="serviceHelper" ref="serviceSwitching" />
    	</bean>
    	<bean id="serviceSwitching" class="ContractServiceWrapper" />
    
    </beans>
    As you said, we find few posts on declaritive caching.
    i'll definitely post entire thing when it works.


    Waiting for your reply & Thanks in advance

    Ganesh
    Last edited by ganeshgadi; Nov 29th, 2007 at 06:19 AM. Reason: data added

  4. #4
    Join Date
    Dec 2005
    Location
    Croatia
    Posts
    192

    Default

    Quote Originally Posted by ganeshgadi View Post
    Which class you are talking about?
    Any class that you use in your application. My example is taken from a DAO class. The entire class definition is not important - the only thing you add to the class you want to have cacheable methods are annotations.

    Quote Originally Posted by ganeshgadi View Post
    Which class you are talking about?
    For example, If it is application class which has business methods to be cached, you might know, we should not touch it.
    Why would you not cache business methods? It is possible to have business method which takes a long time to execute, or uses lots of resources. It would be natural to cache it. And the cache is added as an aspect, so it does not interfere with your business logic.

    Quote Originally Posted by ganeshgadi View Post
    i'm supposed to use CacheProxyFactoryBean strategy.
    To implement and test declarative caching I followed a chapter from "Spring in action 2nd edition". I've never used the approach you posted in your code.

    The code I've given should work as-is. Just use my xml configuration, put an annotation in any class you use in your project and it shoud work. Of course, put the newest spring modules jar.

  5. #5
    Join Date
    Dec 2005
    Location
    Croatia
    Posts
    192

    Default

    Oh, I forgot to mention, the "beans" root element in your configuration must be defined to recognize "ehcache" namespace.
    I use config like this:
    Code:
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
           xsi:schemaLocation="
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
           http://www.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd">
    
    ...
    
    </beans>
    There are a lot of namespace definitions I use here. But "ehcache" is important here.

    I just took a quick look in my book again. There are xml config elements that do the same thing as my annotations, but I never bothered with that as I find annotation cleaner.

  6. #6

    Default

    Quote Originally Posted by imilina View Post
    Why would you not cache business methods? It is possible to have business method which takes a long time to execute, or uses lots of resources. It would be natural to cache it. And the cache is added as an aspect, so it does not interfere with your business logic.
    I don't mean business methods would not be cached. My intension is not to write/add even a single line of code on the business methods that are to be, in fact, cached only, Can't we apply caching mechanism for those methods.

    For example:
    Code:
    //This is the class which has business methods to be cached.
    <bean id="testClass"		class="com.cit.ecommerce.adaptor.registration.TestClass" />
    
    <bean id="testProxyBean"
    		class="org.springmodules.cache.interceptor.proxy.CacheProxyFactoryBean">
    		<property name="cacheProviderFacade" ref="cacheProviderFacade" />
    		<property name="target" ref="testClass" />
    		<property name="cachingModels">
    			<props>
    				<prop key="get*">
    					cacheName=CITeCOMMERCEPORTAL_CACHE;
    				</prop>
    			</props>
    		</property>
    		<property name="flushingModels">
    			<props>
    				<prop key="update*">
    					cacheNames=CITeCOMMERCEPORTAL_CACHE;
    				</prop>
    			</props>
    		</property>
    </bean>
    When we call

    TestClass tc = (TestClass)factory.getBean("testProxyBean");

    Person p = tc.getPerson(..)//to be cached actually.
    Here return value is cached automatically without adding a single line of code on getPerson(..)
    It's working very fine this mechanism. But it caches all getter methods of TestClass automatically which i don't want actually.

    Thanks,
    Ganesh

  7. #7

    Default

    Thanks Imilina,

    I tried as you said.

    I configured like this:

    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:aop="http://www.springframework.org/schema/aop"
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xmlns:ehcache="http://www.springmodules.org/schema/ehcache"
    	xsi:schemaLocation="
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
           http://www.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.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="petsCacheModel" cacheName="CACHE_NAME" />
    		<ehcache:flushing id="petsFlushModel" cacheNames="CACHE_NAME" when="after" />
    	</ehcache:annotations>
    
    <bean id="test" class="com.cit.ecommerce.test.TestCache"/>//This is my 
    new entry
    
    </beans>
    Java Code:

    Code:
    public class TestCache {	
    	
    	@Cacheable(modelId = "petsCacheModel")		
    	public Person getMethod(){
    		
    		return getObject("ABCD",34);
    	}	
    	
    	@Cacheable(modelId = "petsCacheModel")	
    	private Person getObject(String name, int age){
    		
    		Person p = new Person();		
    		p.name = "Sachin";
    		p.age = 25;
    		
    		System.out.println("Called----private method (**)");
    		return p;
    	}
    	@CacheFlush(modelId = "petsFlushModel")	
    	public void updateObject(String name,int age){
    		
    		Person p = new Person();
    		p.name = name;
    		p.age = age;		
    	}	
    	
    }
    TEST CLIENT CODE:

    Code:
    public class Test {
    
    	public static void main(String[] args) {
    		
    //		ApplicationContext ctx = new ClassPathXmlApplicationContext("beans4cache.xml");
    		
    		ClassPathResource resource = new ClassPathResource("CachingInAction.xml");		 
    		BeanFactory factory = new XmlBeanFactory(resource);		
    		TestCache testCache=null;
    		Person p=null;			
    		testCache  = (TestCache)factory.getBean("test");		
    		p = testCache.getMethod();
    		System.out.println("Called---- (1)");
    		p = testCache.getMethod();
    		System.out.println("Called---- (2)");
    		testCache.updateObject("ABCD",22);
    		p = testCache.getMethod();
    		System.out.println("Called---- (3)");
    	}
    }
    OUTPUT:

    Called----private method (**)
    Called---- (1)
    Called----private method (**)
    Called---- (2)
    Called----private method (**)
    Called---- (3)

    It means caching is not working. i'm getting no errors but caching is not happening.

    Waiting for your reply

    Ganesh
    Last edited by ganeshgadi; Nov 29th, 2007 at 09:55 AM. Reason: ADDED READABILITY

  8. #8
    Join Date
    Dec 2005
    Location
    Croatia
    Posts
    192

    Default

    You do know that the annotation added to your service class doesn't actually do anything to your class - it is just a marker interface. Spring does all the proxying when it finds this annotation, while creating the bean.

    But I understand if you don't like using them. There is an alternative configuration option I did not test:
    Code:
    <ehcache:proxy id="rantDao" refId="rantDaoTarget">
        <ehcache:caching methodName="getRantsForDay" cacheName="rantzCache" />
        <ehcache:flushing methodName="saveRant" cacheName="rantzCache" />
    </ehcache:proxy>
    This should create "rantDao" bean, proxying "rantDaoTarget" and adding cache support to method "getRantsForDay()" and cache flushing capability to "saveRant()".

    "rantDaoTarget" is your original class you want to add cache. You need to have "cacheManager" and "cacheProvider" beans declared as well (like I did in my first post). Once again, I did not test this, but I hope it should work the same thing as the example I posted with annotations.

  9. #9
    Join Date
    Dec 2005
    Location
    Croatia
    Posts
    192

    Default

    Quote Originally Posted by ganeshgadi View Post
    i'm getting no errors but caching is not happening.
    Post your "ehcache.xml" configuration that is on your classpath. Do you have "CACHE_NAME" cache defined?

    Also, remove @Cacheable from: public Person getMethod()
    You need to cache the innermost method only, in your case getObject()
    Last edited by imilina; Nov 29th, 2007 at 10:07 AM.

  10. #10

    Default

    Quote Originally Posted by imilina View Post
    <ehcacheroxy id="rantDao" refId="rantDaoTarget">
    <ehcache:caching methodName="getRantsForDay" cacheName="rantzCache" />
    <ehcache:flushing methodName="saveRant" cacheName="rantzCache" />
    </ehcacheroxy>
    I understand this. But thing is i have two methods with the same name.
    I want one of them only to be cached. Of course, arguements differ.

    This is where i'm finding the problem.

    I'll test it now

    Please suggest me on this.

    Thanks in advance

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •