I'm trying to setup my project to use cache (ehcache) with Spring + hibernate in junit mode, and Spring+hibernate+JTA (Glassfish).
here my spring-hiberrnate config for junit
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="springEhcache"/>
</bean>
<bean id="springEhcache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="cacheManagerName" value="method-cache" />
</bean>
<!-- Config Database: ImageManager -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/jdbc.properties" />
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory</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_configuration_file_resource_path">ehcache.xml</prop>
</props>
</property>
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
I annotated some Entity with @Cachable (only entity that I want cached)
@Cacheable
@Entity
@Table(name = "PLATFORM")
public class Plaform ...
and I set some query : setCacheable(true).
@Transactional(readOnly = true)
public List<Platform> listPlatform() {
return sessionFactory.getCurrentSession().createQuery("from Platform").setCacheable(true).list();
}
and I have a object (named CacheMap) with @PostConstruct
that will load some query and populate few Map.
When I lunch my junit my CacheMap object will fetch some data, and after that DBUnit will insert a set of data.
The problem is when I call listPlatform it returns empty, because the query was first called my CacheMap. There is a way to tell Hibernate to invalidate the current cache ?
EDIT :
I added this code like suggested after the insert via DBunit, but when I rerun my query, it's the cached values that are returns.
for (String name : cacheManager.getCacheNames()) {
cacheManager.getCache(name).clear();
}
EDIT 2. I remove the lines suggested and replace them with
sessionFactory.getCache().evictQueryRegions();
sessionFactory.getCache().evictDefaultQueryRegion();
and remove Spring cache from my config and now it works for Query, but no Entity are put into Cache Level 2. I'll continue my tests and post a complete solution.
Here the statistics :
NO CACHE Statistics=Statistics[start time=1388275898144,sessions opened=16,sessions closed=16,transactions=32,successful transactions=16,optimistic lock failures=0,flushes=87,connections obtained=16,statements prepared=1518,statements closed=1518,second level cache puts=0,second level cache hits=0,second level cache misses=0,entities loaded=943,entities updated=3,entities inserted=334,entities deleted=0,entities fetched=64,collections loaded=459,collections updated=149,collections removed=0,collections recreated=200,collections fetched=459,queries executed to database=422,query cache puts=0,query cache hits=0,query cache misses=0,max query time=321]
With CACHE Statistics=Statistics[start time=1388275940458,sessions opened=16,sessions closed=16,transactions=32,successful transactions=16,optimistic lock failures=0,flushes=84,connections obtained=16,statements prepared=1341,statements closed=1341,second level cache puts=0,second level cache hits=0,second level cache misses=0,entities loaded=841,entities updated=3,entities inserted=334,entities deleted=0,entities fetched=93,collections loaded=403,collections updated=149,collections removed=0,collections recreated=200,collections fetched=293,queries executed to database=382,query cache puts=231,query cache hits=40,query cache misses=231,max query time=137]
EDIT 3 :
I found how to cache Entity into Level 2 Cache. It's seem slower when I cached the entity.
cache :read-write Statistics=Statistics[start time=1388278575470,sessions opened=16,sessions closed=16,transactions=32,successful transactions=16,optimistic lock failures=0,flushes=84,connections obtained=16,statements prepared=1377,statements closed=1377,second level cache puts=37,second level cache hits=77,second level cache misses=2,entities loaded=764,entities updated=3,entities inserted=334,entities deleted=0,entities fetched=38,collections loaded=403,collections updated=149,collections removed=0,collections recreated=200,collections fetched=403,queries executed to database=363,query cache puts=233,query cache hits=59,query cache misses=233,max query time=161]
No entity cache Statistics=Statistics[start time=1388278655759,sessions opened=16,sessions closed=16,transactions=32,successful transactions=16,optimistic lock failures=0,flushes=84,connections obtained=16,statements prepared=1333,statements closed=1333,second level cache puts=0,second level cache hits=0,second level cache misses=0,entities loaded=841,entities updated=3,entities inserted=334,entities deleted=0,entities fetched=104,collections loaded=403,collections updated=149,collections removed=0,collections recreated=200,collections fetched=293,queries executed to database=363,query cache puts=233,query cache hits=59,query cache misses=233,max query time=147]
Here my ehcache.xml
<ehcache>
<diskStore path="./resource"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="org.hibernate.cache.StandardQueryCache"
maxElementsInMemory="20"
eternal="false"
timeToLiveSeconds="120"
overflowToDisk="false"/>
<cache name="org.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"/>
</ehcache>
here my pom (a part of it)
<properties>
<spring.version>3.2.5.RELEASE</spring.version>
<hibernate.version>3.6.9.Final</hibernate.version>
</properties>
<!-- Spring 3 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.6</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.5.6-Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>2.4.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>3.7</version>
</dependency>
You need to get your cacheManager, then fetch all the caches and remove them.
Below code sample will give you idea on how to achieve this:
EhCacheCacheManager cacheManager; // injected cacheManger
String[] names = cacheManager.getCacheNames();
for (String name : names)
{
Cache cache = cacheManager.getCache(name);
cache.removeAll();
}
I had to do that
currentSessionFactory = sessionFactory;
sessionFactory.getStatistics().isStatisticsEnabled();
try {
sessionFactory.getCache().evictQueryRegions();
sessionFactory.getCache().evictDefaultQueryRegion();
} catch (Exception e) {
}
and reload my entities. Works fine.
I also have my entity in hibernate.xml
<class-cache usage="read-write" class="entity.Platform" />
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.