27
Hibernate Second Level Cache using EHcache with Spring http://helponjee.blogspot.in/ 2012/03/hibernate-second-level- cache-using.html Hello Friends, After a long try and search from google regarding hibernate second level cache using Ehcache, finally able to up my application with a sound understanding of second level cache behavior in the context of hibernate. **Point to remember one cache configuration can use multiple cache strategies, like hibernate second level as well spring cache using annotation provided by google code project base. Before getting into details let me summarize the reuirement details, I mean specially jar files required to make running hibernate 3.6, spring 3.0> and ehcache 2.4> . Basically we do requires all jar files of Spring3.0 along with RC2 release of spring jars. And for hibernate, we simply requires activation.jar antlr-2.7.7.jar, cglib-2.2.jar, ehcache-core-2.4.2.jar,

Hibernate Second Level Cache Using EHcache With Spring

  • Upload
    md-imam

  • View
    69

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Hibernate Second Level Cache Using EHcache With Spring

Hibernate Second Level Cache using EHcache with Spring

http://helponjee.blogspot.in/2012/03/hibernate-second-level-cache-using.html

Hello Friends,

After a long try and search from google regarding hibernate second level cache using Ehcache, finally able to up my application with a sound understanding of second level cache behavior in the context of hibernate.

**Point to remember one cache configuration can use multiple cache strategies, like hibernate second level as well spring cache using annotation provided by google code project base.

Before getting into details let me summarize the reuirement details, I mean specially jar files required to make running hibernate 3.6, spring 3.0> and ehcache 2.4> .

Basically we do requires all jar files of Spring3.0 along with RC2 release of spring jars.

And for hibernate, we simply requires activation.jarantlr-2.7.7.jar,cglib-2.2.jar,ehcache-core-2.4.2.jar,org.springframework.orm-3.1.0.RC2.jarspring-aop-3.0.5.RELEASE.jarspring-hibernate3-2.0.1.jar

Lets dip into code first ten we will understand the basic use of hibernate and second level cache in context of hibernate and spring.

Here first I need To configure my ehcache.xmlThis contains all entries of the cache name and its policysStep-1:<code>

<?xml version="1.0" encoding="UTF-8"?>

Page 2: Hibernate Second Level Cache Using EHcache With Spring

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xsi:noNamespaceSchemaLocation="ehcache.xsd"        updateCheck="false" monitoring="autodetect"        dynamicConfig="true">    <!--Default Cache configuration. These will be applied to caches programmatically created through the CacheManager.

        The following attributes are required for defaultCache:

        maxInMemory       - Sets the maximum number of objects that will be created in memory        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element is never expired.        timeToIdleSeconds - Sets the time to idle for an element before it expires.                            i.e. The maximum amount of time between accesses before an element expires                            Is only used if the element is not eternal.                            Optional attribute. A value of 0 means that an Element can idle for infinity        timeToLiveSeconds - Sets the time to live for an element before it expires.                            i.e. The maximum time between creation time and when an element expires.                            Is only used if the element is not eternal.        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache                            has reached the maxInMemory limit.

     -->    <diskStore path="java.io.tmpdir"/> <defaultCache            maxElementsInMemory="100"            eternal="true"            timeToIdleSeconds="10000"            timeToLiveSeconds="60000"            overflowToDisk="false"/>     <cache name="com.friendsmirror.login.APP_ID_CACHE"        maxElementsInMemory="1000"        eternal="false"        timeToIdleSeconds="60"        overflowToDisk="true"/>              <cache name="com.friendsmirror.login.USER_ID_EXISTS"        maxElementsInMemory="1000"        eternal="false"        timeToIdleSeconds="60"        overflowToDisk="true"/>            <cache name="IS_USER_ALREDAY_BY_EMAIL_ID"        maxElementsInMemory="50"        eternal="false"        timeToIdleSeconds="0"        overflowToDisk="true"        timeToLiveSeconds="86400"/>      <cache name="com.friendsmirror.register.vo.UserBasicProfileInfoVo" maxElementsInMemory="50" eternal="false" timeToIdleSeconds="0" timeToLiveSeconds="86400" overflowToDisk="true"/> <cache name="org.hibernate.cache.UpdateTimestampsCache" maxElementsInMemory="50" eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="86400" overflowToDisk="true"/> <cache name="org.hibernate.cache.StandardQueryCache" maxElementsInMemory="50" eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="86400" overflowToDisk="true"/> <cache name="query.UserBasicProfilePerEmailId" maxElementsInMemory="50" eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="86400" overflowToDisk="true"/></ehcache>

</code>

Page 3: Hibernate Second Level Cache Using EHcache With Spring

here points to mark is we are providing one default cache configuration as well we are giving some configuration details for the cache with name.

for hibernate we can use the cache name as fully qualified class as the cache name, we need to declare any where it will automatically get mapped from your hmm file.

Second we are giving cache configuration for the updateTimestamp and standard Query cache this is because of, we can cahe HQL, Query to second level as well.

Step-2: Lets configure this ehcahe into our application called spring context:

<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:task="http://www.springframework.org/schema/task"xmlns:ws="http://jax-ws.dev.java.net/spring/core" xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"xmlns:oxm="http://www.springframework.org/schema/oxm" xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd       http://www.springframework.org/schema/context       http://www.springframework.org/schema/context/spring-context-3.0.xsd       http://www.springframework.org/schema/task       http://www.springframework.org/schema/task/spring-task-3.0.xsd       http://jax-ws.dev.java.net/spring/core       http://jax-ws.dev.java.net/spring/core.xsd       http://jax-ws.dev.java.net/spring/servlet       http://jax-ws.dev.java.net/spring/servlet.xsd   http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd" >

<!--  Caching Entries --> <ehcache:annotation-driven cache-manager="ehCacheManager" /> <ehcache:config cache-manager="ehCacheManager"> <ehcache:evict-expired-elements interval="60" /> </ehcache:config>

<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">    <property name="configLocation">      <value>\WEB-INF\ehcache.xml</value>    </property>    </bean>         <!--  End Caching --></beans>

</code>

Here we are registering the ehcahe file and letting the application know that it can use @Cache, @cachable also.

Step-3: After registering the ehcache lets configure our hibernate context in our application context:

<code>

Page 4: Hibernate Second Level Cache Using EHcache With Spring

<?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:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-3.0.xsd" >

<!-- Use this file when using the JNDI data source.  This should be used in the EAR files  deployed to DEV, QA, AND PROD --> <bean id="friendsmirrorDataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:comp/env/jdbc/FriendsMirrorDS</value> </property> <property name="cache"> <value>true</value> </property> <property name="resourceRef"> <value>true</value> </property> <property name="lookupOnStartup"> <value>false</value> </property> <property name="proxyInterface"> <value>javax.sql.DataSource</value> </property> </bean> <!-- Hibernate session factory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

    <property name="dataSource" ref="friendsmirrorDataSource"/>    <property name="hibernateProperties">       <props>         <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>         <prop key="hibernate.show_sql">true</prop>         <!-- <prop key="hibernate.cache.use_second_level_cache">true</prop> <prop key="hibernate.cache.use_query_cache">true</prop> <prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop> --> <prop key="hibernate.current_session_context_class">org.hibernate.context.ThreadLocalSessionContext</prop> <prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop> <prop key="hibernate.cache.use_query_cache">true</prop> <prop key="hibernate.cache.use_second_level_cache">true</prop> <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>  <prop key="hibernate.cache.provider_configuration_file_resource_path">\WEB-INF\ehcache.xml</prop>  <prop key="hibernate.generate_statistics">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.cache.use_structured_entries">true</prop>       </props>     </property>     <property name="mappingResources"> <list> <value>/hibernateMapping/RegisterBasicProfile.hbm.xml</value> <value>/hibernateMapping/userCurrentAddress.hbm.xml</value> <value>/hibernateMapping/UserOfficeAddress.hbm.xml</value> <value>/hibernateMapping/UserUniversityAddress.hbm.xml</value> </list>    </property>

    </bean>        <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean>     <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">    <property name="sessionFactory" ref="sessionFactory" />    </bean>    </beans>

</code>

Page 5: Hibernate Second Level Cache Using EHcache With Spring

Here we are giving the details to hibernate to use the second level cache provided by EHCache.

Point to Remmebr:

Hibernate supports two type of cache, session level and session factory (clustered, Per JVM) 

Normally the methods we use from hibernate i.e save,update,load, get etc which are basically query the database with the help of primary key, we need not to do anything for them it will get auto taken care by application to look up from the cache.

Where as when ever we are using query like find, list etc in this case we need to set explicitly to know by the EHcache Proxy that these data have to write or look up in cache.

Basically when we write query with where clause or with out where clause doesn't matter, but be cosiuos while using where clause, most time we used to include the where clause while building the query, where as its a bad idea and ehcache will not find any key and value  pair to store the object.

Basically ehcahe stores data in key, value pair, so in case of anything missed then we will come up with cache corrupt.

So if we requires anything to specify in where clause , then set it in prepared query style, so that it will have a valid key to store in cache.

Please remember the above points strictly else you will come up with cache hit is not working for find, list and all where as the same thing will work for load and get.

Step-4: Next move to our sample hbm.xml to define the calass mapping with table and give the cache details:

<code>

<hibernate-mapping>    <class name="com.friendsmirror.register.vo.UserBasicProfileInfoVo" table="user_profile" lazy="true">    <cache usage="read-write"/>        <id name="profileId" type="java.lang.Integer">            <column name="profile_id" />            <generator class="increment" />        </id>        <property name="firstName" type="java.lang.String">            <column name="first_name" length="100" not-null="true"/>        </property>        <property name="middelName" type="java.lang.String">            <column name="middel_name" length="100" not-null="false"/>        </property>

Page 6: Hibernate Second Level Cache Using EHcache With Spring

        <property name="lastName" type="java.lang.String">            <column name="last_name" length="100" not-null="false"/>        </property>        <property name="gender" column="gender" length="6" not-null="true">        <type name="org.hibernate.type.EnumType">        <param name="enumClass">com.friendsmirror.register.bean.Gender</param>        <param name="type">12</param>        </type>        </property>        <property name="sexualType" column="sexual_type" length="10" not-null="false">        <type name="org.hibernate.type.EnumType">        <param name="enumClass">com.friendsmirror.register.bean.SexualType</param>        <param name="type">12</param>        </type>        </property>        <property name="dateOfBirth" type="java.lang.String">            <column name="birth_date" length="2" not-null="false"/>        </property>        <property name="monthOfBirth" type="java.lang.String">            <column name="birth_month" length="2" not-null="false"/>        </property>        <property name="yearOfBirth" type="java.lang.String">            <column name="birth_year" length="4" not-null="false"/>        </property>        <property name="emailId" type="java.lang.String">            <column name="email_id" length="100" not-null="true" unique="true"/>        </property>        <property name="mobileNumber" type="java.lang.String">            <column name="mobile_number" length="10" not-null="false"/>        </property>        <property name="phoneNumber" type="java.lang.String">            <column name="phone_number" length="14" not-null="false"/>        </property>        <property name="occupationType" column="occupation_typee" length="20" not-null="false">            <type name="org.hibernate.type.EnumType">        <param name="enumClass">com.friendsmirror.register.bean.Occupation</param>        <param name="type">12</param>        </type>        </property>    </class></hibernate-mapping>

</code>

here in the second line we are giving instructions to use the cache on read-write basics, basically there are much more options refer to the ehcahe and hibernate integration official site to choose one for you.

Here remember as earlier mentioned, the class name mapped in the table will become our cache name for the methods/api directly querying the db with primary key, SO you can see I have given a entry to the ehcahe with the mapped class name.

If you have only requirement with load and get basically primary key as retrieval id then you are done, you ned to follow the monitoring section which will give you complete picture of your cache details.

Step-5: Now in case you decided to use, Query api , Its actually a bad idea to cache the things on the basics of query where as i sometimes helpful in order to store the object graph of a complex query.

see the code snap let below in case you decided for query:

<code>

Page 7: Hibernate Second Level Cache Using EHcache With Spring

UserBasicProfileInfoVo userBasicProfileInfoVo = null; boolean userExistsFlg = Boolean.FALSE; Session session = null; try{ session = friendsMirrorSessionFactoryService.getFriendsMirrorSession();

String queryStr = " From UserBasicProfileInfoVo where email_id = :emailId";

if(logger.isDebugEnabled()){ logger.debug("Trying to get the user with Email Id : "+userBasic.getEmailId()); logger.debug("The Query for the same is : "+ queryStr); } Query query =  session.createQuery(queryStr).setCacheable(true); query.setCacheRegion(FriendsMirrorRegister.QUERY_IS_USER_EXISTS); query.setString("emailId", userBasic.getEmailId()); userBasicProfileInfoVo = (UserBasicProfileInfoVo) query.uniqueResult(); if(logger.isDebugEnabled()){ friendsMirrorSessionFactoryService.logCacheStaticsDetails(FriendsMirrorRegister.QUERY_IS_USER_EXISTS); } if(userBasicProfileInfoVo != null){ userExistsFlg = Boolean.TRUE; } }catch (HibernateException e) { friendsMirrorSessionFactoryService.closeFriendsMirrorSession(session); logger.error("Exception Occured while cheking for the user: "+userBasic.getEmailId()+ e); throw new FriendsMirrorSystemException(FriendsMirrorRegister.__DB_DOWN, FriendsMirrorRegister._DB_EXCEPTION); }catch (HibernateJdbcException e) { friendsMirrorSessionFactoryService.closeFriendsMirrorSession(session); logger.error("Exception Occured while cheking for the user: "+userBasic.getEmailId()+ e); throw new FriendsMirrorSystemException(FriendsMirrorRegister.__DB_DOWN, FriendsMirrorRegister._DB_EXCEPTION); }catch (Exception e) { friendsMirrorSessionFactoryService.closeFriendsMirrorSession(session); logger.error("catched Exception from parent:" + e.getMessage()); if(e instanceof FriendsMirrorSystemException){ throw (FriendsMirrorSystemException)e; }else{ throw new FriendsMirrorSystemException(FriendsMirrorRegister._REGISTER_SYSTEM_ERROR_MSG,FriendsMirrorRegister._REGISTER_SYSTEM_ERROR); } } friendsMirrorSessionFactoryService.closeFriendsMirrorSession(session); return userExistsFlg; }

}

</code>

here if you will see, I have a service which is returning me session until things: the code of that service is as follows:

Page 8: Hibernate Second Level Cache Using EHcache With Spring

<code>

package com.friendsmirror.register.hibernate;

import org.apache.log4j.Logger;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.stat.SecondLevelCacheStatistics;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.orm.hibernate3.HibernateTemplate;

public class FriendsMirrorSessionFactoryServiceImpl implements FriendsMirrorSessionFactoryService {

private HibernateTemplate hibernateTemplate; private static Logger logger = Logger.getLogger(FriendsMirrorSessionFactoryServiceImpl.class); @Autowired public void setHibernateTemplate(HibernateTemplate hibernateTemplate) { this.hibernateTemplate = hibernateTemplate; }

/** * <p> method to open a new session */ @Override public Session getFriendsMirrorSession() { SessionFactory sessionFactory = getFriendsMirrorSessionFactory(); return sessionFactory.openSession(); } /** * <p> Method to get the current sessionFactory * @return {@link SessionFactory} */ private SessionFactory getFriendsMirrorSessionFactory() { return hibernateTemplate.getSessionFactory(); }

/** * <p> method to close the current active session * @param

Page 9: Hibernate Second Level Cache Using EHcache With Spring

*/ @Override public void closeFriendsMirrorSession(Session session) { if(session.isOpen()) session.close(); }

/* * (non-Javadoc) * @see com.friendsmirror.register.hibernate.FriendsMirrorSessionFactoryService#logCacheStaticsDetails(java.lang.String) */ @Override public void logCacheStaticsDetails(String cacheName) { SessionFactory sessionFactory = getFriendsMirrorSessionFactory(); org.hibernate.stat.Statistics statistics = sessionFactory.getStatistics(); SecondLevelCacheStatistics settingsStatistics = statistics.getSecondLevelCacheStatistics(cacheName); if(settingsStatistics != null){ StringBuffer sb = new StringBuffer(); sb.append("\n************************************************\n"); sb.append("SucessFull Hit Count for cache name: "+ cacheName+" is: " + settingsStatistics.getHitCount()+"\n"); sb.append("Missed Hit Count for the cache name: "+ cacheName+" is: " + settingsStatistics.getMissCount()+"\n"); sb.append("Number of elemnt put into the cache named: "+cacheName+" is: "+settingsStatistics.getPutCount()+"\n"); sb.append("Size occupied in disk space by the cache named: "+ cacheName+" is: "+settingsStatistics.getSizeInMemory()+"\n"); sb.append("Number of elemnt available for the cache nameed: "+ cacheName+" in memory is: "+settingsStatistics.getElementCountInMemory()+"\n"); sb.append("Number of elemnt available for the cache nameed: "+ cacheName+" in disk space is: "+settingsStatistics.getElementCountOnDisk()+"\n"); sb.append("*************************************************"); logger.info("Cache Report for "+cacheName+" are below"+sb.toString()); } }

}

Page 10: Hibernate Second Level Cache Using EHcache With Spring

</code>

mark the below line from the daoImpl class:<code>

String queryStr = " From UserBasicProfileInfoVo where email_id = :emailId";

if(logger.isDebugEnabled()){ logger.debug("Trying to get the user with Email Id : "+userBasic.getEmailId()); logger.debug("The Query for the same is : "+ queryStr); } Query query =  session.createQuery(queryStr).setCacheable(true); query.setCacheRegion(FriendsMirrorRegister.QUERY_IS_USER_EXISTS); query.setString("emailId", userBasic.getEmailId());

</cdoe> Here we are creating a query with a parameter we need to pass, so when we will create query from that string we need to set the where clause parameter, as query.setString.

Also we are telling that cache this query and use the configuration details mentioned in our ehache i.e:<code>

query.UserBasicProfilePerEmailId

</code>

Test Senario:

Now Finally you are done.

Create a junit test case, load the application context or you can simply follow the testMain approach and load your application context and get the bin of daoImpl,

And call the method IsUserExists,

Inside that, I am calling one<code>

@Override public void logCacheStaticsDetails(String cacheName) { SessionFactory sessionFactory = getFriendsMirrorSessionFactory(); org.hibernate.stat.Statistics statistics = sessionFactory.getStatistics(); SecondLevelCacheStatistics settingsStatistics = statistics.getSecondLevelCacheStatistics(cacheName); if(settingsStatistics != null){ StringBuffer sb = new StringBuffer(); sb.append("\n************************************************\n"); sb.append("SucessFull Hit Count for cache name: "+ cacheName+" is: " + settingsStatistics.getHitCount()+"\n"); sb.append("Missed Hit Count for the cache name: "+ cacheName+" is: " + settingsStatistics.getMissCount()+"\n"); sb.append("Number of elemnt put into the cache named: "+cacheName+" is: "+settingsStatistics.getPutCount()+"\n"); sb.append("Size occupied in disk space by the cache named: "+ cacheName+" is: "+settingsStatistics.getSizeInMemory()+"\n"); sb.append("Number of elemnt available for the cache nameed: "+ cacheName+" in memory is: "+settingsStatistics.getElementCountInMemory()+"\n");

Page 11: Hibernate Second Level Cache Using EHcache With Spring

sb.append("Number of elemnt available for the cache nameed: "+ cacheName+" in disk space is: "+settingsStatistics.getElementCountOnDisk()+"\n"); sb.append("*************************************************"); logger.info("Cache Report for "+cacheName+" are below"+sb.toString()); } }

</code>

here I am getting the statics details for the cache we passed as argument to this method,Remember if no cache will be associated then you will get a null object of SecondLevelCacheStatistics  which will give you null pointer exception to avoid that ,make a not null check print the details of that cache.

In the test main you need to call the method only once, run that test main multiple times or junit test case multiple times to see a

cache hit will increase where as you missed cache hit will be constant may be 1, as first time it don't have any object on cache.

Console log In My case:

First Time Running the client:

21:56:16,244 INFO  [StandardQueryCache] starting query cache at region: query.UserBasicProfilePerEmailId21:56:16,259 INFO  [STDOUT] Hibernate:     select        userbasicp0_.profile_id as profile1_8_,        userbasicp0_.first_name as first2_8_,        userbasicp0_.middel_name as middel3_8_,        userbasicp0_.last_name as last4_8_,        userbasicp0_.gender as gender8_,        userbasicp0_.sexual_type as sexual6_8_,        userbasicp0_.birth_date as birth7_8_,        userbasicp0_.birth_month as birth8_8_,        userbasicp0_.birth_year as birth9_8_,        userbasicp0_.email_id as email10_8_,        userbasicp0_.mobile_number as mobile11_8_,        userbasicp0_.phone_number as phone12_8_,        userbasicp0_.occupation_typee as occupation13_8_     from        user_profile userbasicp0_     where        email_id=?21:56:16,322 INFO  [STDOUT] [2012-56-10 09:56, 65553]INFO [http-127.0.0.1-8080-1](FriendsMirrorSessionFactoryServiceImpl.java:72) - Cache Report for query.UserBasicProfilePerEmailId are below************************************************SucessFull Hit Count for cache name: query.UserBasicProfilePerEmailId is: 0Missed Hit Count for the cache name: query.UserBasicProfilePerEmailId is: 1Number of elemnt put into the cache named: query.UserBasicProfilePerEmailId is: 1Size occupied in disk space by the cache named: query.UserBasicProfilePerEmailId is: 1854Number of elemnt available for the cache named: query.UserBasicProfilePerEmailId in memory is: 1Number of elemnt available for the cache nameed: query.UserBasicProfilePerEmailId in disk space is: 0************************************************* -logCacheStaticsDetails

Second TIme:

21:57:36,544 INFO  [STDOUT] [2012-57-10 09:57,145774]INFO [http-127.0.0.1-8080-1](UserRegisterControllerImpl.java:35) - Request Recieved to register new user with basic data, which will make a intial entery for the user -registerAFirstTimeUser

Page 12: Hibernate Second Level Cache Using EHcache With Spring

21:57:36,544 INFO  [STDOUT] BEST_FRIENDS21:57:36,544 INFO  [STDOUT] [2012-57-10 09:57,145775]INFO [http-127.0.0.1-8080-1](RegistrationServiceImpl.java:42) - Intial step for regestering the basic profile transaction starts from here, in case of any issue with data or system,database will get roll back -registerBasicProfile21:57:36,548 INFO  [STDOUT] [2012-57-10 09:57,145778]INFO [http-127.0.0.1-8080-1](RegisterationValidationServiceImpl.java:50) - Request Recived to validate the user profile before user get created with the following info : [First Name: null, Email Id: [email protected]] -validateBasicUserProfile21:57:36,551 INFO  [STDOUT] [2012-57-10 09:57,145781]INFO [http-127.0.0.1-8080-1](FriendsMirrorSessionFactoryServiceImpl.java:72) - Cache Report for query.UserBasicProfilePerEmailId are below************************************************SucessFull Hit Count for cache name: query.UserBasicProfilePerEmailId is: 1Missed Hit Count for the cache name: query.UserBasicProfilePerEmailId is: 2Number of elemnt put into the cache named: query.UserBasicProfilePerEmailId is: 2Size occupied in disk space by the cache named: query.UserBasicProfilePerEmailId is: 3707Number of elemnt available for the cache named: query.UserBasicProfilePerEmailId in memory is: 2Number of elemnt available for the cache nameed: query.UserBasicProfilePerEmailId in disk space is: 0*************************************************

This is the small details of use of second level cache with hibernate and spring.

Please let me know in case of any questions or error you are facing with stack trace will try to resolve the same.

Thanks,Jayaram.

----------------------------------******************------------------------------------------

http://eiconsulting.blogspot.in/2011/10/ehcache-implementation-in-spring.html

EhCache Integration with Spring and Hibernate. Step by Step Tutorial EhCache is a very popular open source caching framework widely used for Java based Caching.

Currently it’s owned by Terracotta.org and 2.5 beta releases is available for download.

In this article I just focused on EhCache Integration with Spring and Hibernate also I just explained few basic concepts which are required to understand Code. For detailed Caching Concepts Please visit http://ehcache.org/

Cache Manager, Caches and Elements are main entities of EhCache

Page 13: Hibernate Second Level Cache Using EHcache With Spring

EhCache consists of a CacheManager, which manages Caches. Caches contain Elements, which are essentially name value pairs. Caches are physically implemented either in-memory, or on disk.

Integration with Spring

EhCache integration with Spring is quite simple. You just need to define some properties in spring configuration xml file and its ready to use. Spring is using Annotation to integrate EhCache and by this we can add caching to any method results

EhCache Annotations for Spring is available via maven, simply add the following dependency to your pom.xml 

 

Next Step is to perform changes in your spring Configuration file. Below is my Spring configuration file which contains EhCache configurations

Page 14: Hibernate Second Level Cache Using EHcache With Spring

Important point to note here is that Cache Manager Name and its Configuration Location. We can use cacheManager in our code to store and retrieve information from Cache.

ehcache.xml file is configuration file for EhCache where we can define configuration details of EhCache. In my case here is content of my ehcache.xml file

Page 15: Hibernate Second Level Cache Using EHcache With Spring

Here it’s clear that we have created a cache with name Customer, I will use this Cache to store Customer details

Next step is to use it in your code. In my example I created a simple Spring based application where we have Customer Controller which is used to retrieve Customer Information

We have Customer Object with Customer Id, name and address details and related setter getter methods

Next step is to create Controller. Customer Controller is very simple. I am using Spring Restful Web services to retrieve Customer Information. In my Controller I have no logic related to EhCache. I just have two versions of getCustomer method (one with Annotation and one without Annotation), save Customer and Clear Cache method. Code is simple and self explanatory for any Spring MVC developer.

Page 16: Hibernate Second Level Cache Using EHcache With Spring
Page 17: Hibernate Second Level Cache Using EHcache With Spring
Page 18: Hibernate Second Level Cache Using EHcache With Spring

If you notice Controller is calling Customer Service. Customer Service is our main class and it’s used to get Customer Information. It can get information from Database using Hibernate or from any backend. Here I just provided basic implementation. Idea is to understand usage of EhCache

Following Service methods are used to retrieve and store information in Cache

Previously we have defined “cacheManager” object in our Spring.xml file and also we have defined a Cache with name “customer” in ehcache.xml file. Its time to use both these configurations

getCache method is use to retrieve Cache Object and we are storing new Element in this cache. Element requires key, value pair so I am using id filed as a key. Later on we can use same key to retrieve Customer Object from Cache.

Another great way of using EhCache is Spring Annotation

Page 19: Hibernate Second Level Cache Using EHcache With Spring

Add Cacheable Annotation to methods you would like to cache. In our case we are using it for getCustomer method. If we call getCustomer method with customerId 1, first time complete method will be called. If we will call this method again with same customerId then response will be returned from Cache.

To Clear Cache we can just use TriggerRemove Annotation

 

Complete Source Code is present at following location

https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0B0YFdqXJcI3mY2ZiYzA4NWQtNmQ0ZS00ZWM0LTlkMzktMmM3YmJmZjUzNDEy &hl=en_US

Integration with Hibernate as a Second Level Cache

Hibernate uses different type of Caches

         The first cache type is the session cache. The session cache caches object within the current session.

         The second cache type is the query Cache. The query cache is responsible for caching queries and their results.

         The third cache type is the second level cache. The second level cache is responsible for caching objects across sessions.

EhCache is used as second level cache. EhCache integration with Hibernate is quite simple as well. You just need to define some properties in persistence.xml file.

EhCache jars are available via maven, simply add the following dependency to your pom.xml 

 

Next step is to perform changes in persistence.xml 

Page 20: Hibernate Second Level Cache Using EHcache With Spring

 

 Put ehcache.xml at your classpath. It could be in classes or WEB-INF folder

 

In you Entity just add Annotations related to ehcache and thats it.

 

Complete Source Code is present at following location

-----------------------------*****-------------------------------

3841621

Page 21: Hibernate Second Level Cache Using EHcache With Spring

Why String is immutable or final in Java This is one of the most popular String Interview questions in Java, which starts with discussion of,  What is String, How String in Java is different than String in C and C++, and then shifted towards what is immutable object in Java , what are the benefits of immutable object , why do you use it and which scenarios do you use it. This is some time also asked as "Why String is final in Java" . Though there could be many possible answer for this question, and only designer of String class can answer this , I think below two does make sense

1) Imagine StringPool facility without making string immutable , its not possible at all because in case of string pool one string object/literal e.g. "Test" has referenced by many reference variables , so if any one of them change the value others will be automatically gets affected i.e. lets say

String A = "Test"String B = "Test"

Now String B called "Test".toUpperCase() which change the same object into "TEST" , so A will also be "TEST" which is not desirable.

2)String has been widely used as parameter for many Java classes e.g. for opening network connection, you can pass hostname and port number as string , you can pass database URL as string for opening database connection, you can open any file in Java by passing name of file as argument to File I/O classes.

Page 22: Hibernate Second Level Cache Using EHcache With Spring

In case, if String is not immutable, this would lead serious security threat , I mean some one can access to any file for which he has authorization, and then can change the file name either deliberately or accidentally and gain access of those file. Because of immutability, you don't need to worry about those kind of threats. This reason also gel with, Why String is final in Java, by making java.lang.String final, Java designer ensured that no one overrides any behavior of String class.

3)Since String is immutable it can safely shared between many threads ,which is very important for multithreaded programming and to avoid any synchronization issues in Java, Immutability also makes String instance thread-safe in Java, means you don't need to synchronize String operation externally. Another important point to note about String is memory leak caused by SubString, which is not a thread related issues but something to be aware of.

4) Another reason of Why String is immutable in Java is to allow String to cache its hashcode , being immutable String in Java caches its hashcode, and do not calculate every time we call hashcode method of String, which makes it very fast as hashmap key to be used in hashmap in Java.  This one is also suggested by  Jaroslav Sedlacek in comments below. In short because String is immutable, no one can change its contents once created which guarantees hashCode of String to be same on multiple invocation.

5) Another good reason of Why String is immutable in Java suggested by Dan Bergh Johnsson on comments is: The absolutely most important reason that String is immutable is that it is used by the class loading mechanism, and thus have profound and fundamental security aspects. Had String been mutable, a request to load "java.io.Writer" could have been changed to load "mil.vogoon.DiskErasingWriter"

Security and String pool being primary reason of making String immutable, I believe there could be some more very convincing reasons as well, Please post those reasons as comments and I will include those on this post. By the way, above reason holds good to answer, another Java interview questions "Why String is final in Java".  Also to be immutable you have to be final, so that your subclass doesn't break immutability.  what do you guys think ?

Read more: http://javarevisited.blogspot.com/2010/10/why-string-is-immutable-in-java.html#ixzz2npTAAFbX

----------------------------------------------*****************----------------------------------

http://www.laliluna.de/jpa-hibernate-guide/pt01.html