JavaBeigner
JavaBeigner

Reputation: 607

Second level cache not working With Spring and JSF

I am using Hibernate4+Spring4.0.3.RELEASE+JSF2.0+hibernate-ehcache4.1.0Final for my web application I have implemented second level cache in my project but it not working Here are code

applicationContext.xml file (Inside WEB-INF folder)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:sec="http://www.springframework.org/schema/security"
    xsi:schemaLocation="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
 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
 http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
 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.xsd
 http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">


    <ehcache:annotation-driven />

    <ehcache:config cache-manager="cacheManager">
        <ehcache:evict-expired-elements
            interval="60" />
    </ehcache:config>

    <bean id="cacheManager"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="/WEB-INF/ehcache.xml" />

    </bean>

    <context:component-scan base-package="com.ccc.spring" />

    <context:annotation-config />
    <context:spring-configured />


    <!-- Data Source Declaration -->

    <bean id="DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test" />
        <property name="user" value="user" />
        <property name="password" value="password" />
        <property name="maxPoolSize" value="2" />
        <property name="maxStatements" value="0" />
        <property name="minPoolSize" value="1" />


    </bean>


    <!-- Session Factory Declaration -->
    <bean id="SessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="DataSource" />

        <property name="packagesToScan"> <list> <value>com.ccc.spring.model</value> 
            </list> </property>
        <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.provider_class">org.hibernate.cache.EhCacheProvider</prop>
                <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
                </prop>


                <!--useful for debugging -->
                <prop key="hibernate.generate_statistics">true</prop>
            </props>
        </property>

        <!-- <property name="loadTimeWeaver"> <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" 
            /> </property> <property name="persistenceUnitName" value="danielme_persistenceunit" 
            /> -->

    </bean>

    <!-- Enable the configuration of transactional behavior based on annotations -->
    <tx:annotation-driven transaction-manager="txManager" />

    <!-- Transaction Manager is defined -->
    <bean id="txManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="SessionFactory" />
    </bean>

</beans>

ehcache.xml file(Inside WEB-INF folder)

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

    <defaultCache maxElementsInMemory="100" eternal="false"
        timeToIdleSeconds="120" timeToLiveSeconds="20000" />
    <cache name="ValidUserRole" maxElementsInMemory="100"
        eternal="false" timeToIdleSeconds="5" timeToLiveSeconds="20000" />

In DAO file i am using below code

 @Cacheable( value = "ValidUserRole" )
    public List<Validuserrole> getRoleList() {
        List list = null;
        try{
          list = getSessionFactory().getCurrentSession()
                .createQuery("from Validuserrole ").list();
        }
        catch(Exception e){
            e.printStackTrace();
        }
        return list;
    }

but when i am debugging code its fetch data from DB everytime not taking from second level cache

Upvotes: 2

Views: 1471

Answers (1)

M. Deinum
M. Deinum

Reputation: 124526

You are mixing 2 different things hibernates second level caching and Springs caching support, those are two different beasts. You are trying to mix both of them. What makes it worse is that you are trying to use Spring-Ehcache which is basically the predecessor of Springs own caching support.

Caching Method Results

For starters remove the spring-ehcache stuff and switch to the spring provided caching support. This should make the @Cacheable annotation work. If that is what you want, instead of second level caching you are done.

<?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"
    http://www.springframework.org/schema/cache
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:sec="http://www.springframework.org/schema/security"
    xsi:schemaLocation="
                 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
                 http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
                 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
                 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

<cache:annotation-driven />

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
    <constructor-arg ref="ehcacheManager" />
</bean>

<bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="configLocation" value="/WEB-INF/ehcache.xml" />
</bean>

Note: It is also suggested to use versionless xsd files, this way you ensure that you always use schema files which belong to your Spring version.

Second Level Caching

For second level caching to work you have to understand how it works, first your entity has to be cacheable if that isn't the case nothing is going to be cached.

@Entity
@Cacheable // Note this is from hibernate NOT spring!!!
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Validuserrole { ... }

Next the query will be executed however the resulting objects, when cacheable, will be held in memory. Then for the next time the same entity instance is needed the one from the cache will be returned.

Query Caching

If you want to enable query caching you have to make the query cacheable else it won't be cached.

list = getSessionFactory().getCurrentSession()
            .createQuery("from Validuserrole ")
            .setCacheable(true)
            .list();

Upvotes: 3

Related Questions