我正在尝试设置我的项目在junit模式下使用带有Spring + hibernate的缓存(ehcache),以及Spring + hibernate + JTA(Glassfish)。
这里是我的spring-hiberrnate配置为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>
我用@Cachable注释了一些实体(只有我想要缓存的实体)
@Cacheable
@Entity
@Table(name = "PLATFORM")
public class Plaform ...
我设置了一些查询:setCacheable(true)。
@Transactional(readOnly = true)
public List<Platform> listPlatform() {
return sessionFactory.getCurrentSession().createQuery("from Platform").setCacheable(true).list();
}
我有一个带有@PostConstruct
的对象(名为CacheMap)将加载一些查询并填充少量Map。
当我在junit吃午餐时,我的CacheMap对象将获取一些数据,之后DBUnit将插入一组数据。
问题是当我调用listPlatform时它返回空,因为查询首先被称为我的CacheMap。有一种方法可以告诉Hibernate使当前缓存无效吗?
编辑:
我在插入后通过DBunit添加了此代码,但是当我重新运行查询时,它是返回的缓存值。
for (String name : cacheManager.getCacheNames()) {
cacheManager.getCache(name).clear();
}
编辑2.我删除建议的行并用
替换它们sessionFactory.getCache().evictQueryRegions();
sessionFactory.getCache().evictDefaultQueryRegion();
并从我的配置中删除Spring缓存,现在它适用于Query,但没有实体进入缓存级别2.我将继续我的测试并发布完整的解决方案。
这里有统计数据:
没有CACHE 统计=统计[开始时间= 1388275898144,会话开启= 16,会话关闭= 16,交易= 32,成功交易= 16,乐观锁定失败= 0,刷新= 87,获得连接= 16,语句准备= 1518,报表关闭= 1518,二级缓存put = 0,二级缓存命中= 0,二级缓存未命中= 0,实体已加载= 943,实体已更新= 3,实体已插入= 334,实体已删除= 0,实体已获取= 64,集合loaded = 459,集合已更新= 149,集合已删除= 0,集合已重新创建= 200,集合已取出= 459,查询已执行到数据库= 422,查询缓存放置= 0,查询缓存命中数= 0,查询缓存未命中数= 0,最大值查询时间= 321]
使用CACHE 统计=统计[开始时间= 1388275940458,会话开启= 16,会话关闭= 16,事务= 32,成功事务= 16,乐观锁定失败= 0,刷新= 84,获得连接= 16,语句准备= 1341,语句已关闭= 1341,二级缓存put = 0,二级缓存命中= 0,二级缓存未命中= 0,实体已加载= 841,实体已更新= 3,实体已插入= 334,实体已删除= 0,实体已获取= 93,集合loaded = 403,集合已更新= 149,集合已删除= 0,集合已重新创建= 200,集合已取出= 293,查询已执行到数据库= 382,查询缓存放置= 231,查询缓存命中数= 40,查询缓存未命中数= 231,最大值查询时间= 137]
编辑3:
我找到了如何将实体缓存到二级缓存中。当我缓存实体时,它似乎变慢了。
缓存:读写 统计=统计[开始时间= 1388278575470,会话开启= 16,会话关闭= 16,交易= 32,成功交易= 16,乐观锁定失败= 0,刷新= 84,获得连接= 16,语句准备= 1377,语句已关闭= 1377,二级缓存puts = 37,二级缓存命中= 77,二级缓存未命中= 2,实体已加载= 764,实体已更新= 3,实体已插入= 334,实体已删除= 0,实体已获取= 38,集合loaded = 403,集合已更新= 149,集合已删除= 0,集合已重新创建= 200,集合已取出= 403,查询已执行到数据库= 363,查询缓存放置= 233,查询缓存命中数= 59,查询缓存未命中数= 233,最大值查询时间= 161]
没有实体缓存 统计=统计[开始时间= 1388278655759,会话开启= 16,会话关闭= 16,交易= 32,成功交易= 16,乐观锁定失败= 0,刷新= 84,获得连接= 16,语句准备= 1333,语句已关闭= 1333,二级缓存put = 0,二级缓存命中= 0,二级缓存未命中= 0,实体已加载= 841,实体已更新= 3,实体已插入= 334,实体已删除= 0,实体已获取= 104,集合loaded = 403,集合已更新= 149,集合已删除= 0,集合已重新创建= 200,集合已取出= 293,查询已执行到数据库= 363,查询缓存放置= 233,查询缓存命中数= 59,查询缓存未命中数= 233,最大值查询时间= 147]
这是我的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>
这里是我的pom(它的一部分)
<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>
答案 0 :(得分:0)
您需要获取cacheManager,然后获取所有缓存并将其删除。
下面的代码示例将为您提供有关如何实现此目标的建议:
EhCacheCacheManager cacheManager; // injected cacheManger
String[] names = cacheManager.getCacheNames();
for (String name : names)
{
Cache cache = cacheManager.getCache(name);
cache.removeAll();
}
答案 1 :(得分:0)
我必须这样做
currentSessionFactory = sessionFactory;
sessionFactory.getStatistics().isStatisticsEnabled();
try {
sessionFactory.getCache().evictQueryRegions();
sessionFactory.getCache().evictDefaultQueryRegion();
} catch (Exception e) {
}
并重新加载我的实体。工作正常。
我的实体也在hibernate.xml
中<class-cache usage="read-write" class="entity.Platform" />