我如何在我的 JUnit 测试中强制命中我的二级缓存?
How do I force a hit in my second-level cache in my JUnit test?
我正在使用 Hibernate 4.3。11.Final 以及随附的 ehcache 模块。我想在 JUnit (v 4.11) 测试中验证我的二级缓存是否配置正确,但我不知道如何强制这种情况。我有一个通过 id 检索实体的简单方法,它是
public T findById(final Serializable id)
{
T ret = null;
if (id != null)
{
ret = (T) m_entityManager.find(persistentClass, id);
} // if
return ret;
}
然后在我的 JUnit 测试中我有这个
@Test
public void testSecondLevelCache()
{
long hitCount = m_cache.getStatistics().getCacheHits();
final String countryId = m_testProps.getProperty("test.country.id");
m_countryDao.findById(countryId);
m_countryDao.findById(countryId);
但是第二次调用会命中Hiberntae的一级缓存,重复调用DAO方法也会命中Hibernate的一级缓存。如何强制命中二级缓存?
编辑: 下面是在我的 Spring 应用程序上下文中配置事务管理器和其他相关部分的方式...
<cache:annotation-driven />
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cacheManager-ref="ehcache"/>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache.xml"
p:shared="true" />
<util:map id="jpaPropertyMap">
<entry key="hibernate.show_sql" value="true" />
<entry key="hibernate.dialect" value="org.mainco.subco.core.jpa.SubcoMysql5Dialect" />
<entry key="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" />
<entry key="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
<entry key="hibernate.cache.use_second_level_cache" value="true" />
<entry key="hibernate.cache.use_query_cache" value="false" />
<entry key="hibernate.generate_statistics" value="true" />
<entry key="javax.persistence.sharedCache.mode" value="ENABLE_SELECTIVE" />
</util:map>
<bean id="sharedEntityManager"
class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
首先,您需要从测试或 class 级别中删除 @Transactional
注释,以便您手动控制事务。
其次,您需要更改测试以使用具有两个 EntityManager
个实例的两个连续事务。
@Test
public void testSecondLevelCache() {
long hitCount = m_cache.getStatistics().getCacheHits();
final String countryId = m_testProps.getProperty("test.country.id");
transactionTemplate.execute((TransactionCallback<Void>) transactionStatus -> {
m_countryDao.findById(countryId);
return null;
});
transactionTemplate.execute((TransactionCallback<Void>) transactionStatus -> {
m_countryDao.findById(countryId);
return null;
});
}
我正在使用 Hibernate 4.3。11.Final 以及随附的 ehcache 模块。我想在 JUnit (v 4.11) 测试中验证我的二级缓存是否配置正确,但我不知道如何强制这种情况。我有一个通过 id 检索实体的简单方法,它是
public T findById(final Serializable id)
{
T ret = null;
if (id != null)
{
ret = (T) m_entityManager.find(persistentClass, id);
} // if
return ret;
}
然后在我的 JUnit 测试中我有这个
@Test
public void testSecondLevelCache()
{
long hitCount = m_cache.getStatistics().getCacheHits();
final String countryId = m_testProps.getProperty("test.country.id");
m_countryDao.findById(countryId);
m_countryDao.findById(countryId);
但是第二次调用会命中Hiberntae的一级缓存,重复调用DAO方法也会命中Hibernate的一级缓存。如何强制命中二级缓存?
编辑: 下面是在我的 Spring 应用程序上下文中配置事务管理器和其他相关部分的方式...
<cache:annotation-driven />
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cacheManager-ref="ehcache"/>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache.xml"
p:shared="true" />
<util:map id="jpaPropertyMap">
<entry key="hibernate.show_sql" value="true" />
<entry key="hibernate.dialect" value="org.mainco.subco.core.jpa.SubcoMysql5Dialect" />
<entry key="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" />
<entry key="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
<entry key="hibernate.cache.use_second_level_cache" value="true" />
<entry key="hibernate.cache.use_query_cache" value="false" />
<entry key="hibernate.generate_statistics" value="true" />
<entry key="javax.persistence.sharedCache.mode" value="ENABLE_SELECTIVE" />
</util:map>
<bean id="sharedEntityManager"
class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
首先,您需要从测试或 class 级别中删除 @Transactional
注释,以便您手动控制事务。
其次,您需要更改测试以使用具有两个 EntityManager
个实例的两个连续事务。
@Test
public void testSecondLevelCache() {
long hitCount = m_cache.getStatistics().getCacheHits();
final String countryId = m_testProps.getProperty("test.country.id");
transactionTemplate.execute((TransactionCallback<Void>) transactionStatus -> {
m_countryDao.findById(countryId);
return null;
});
transactionTemplate.execute((TransactionCallback<Void>) transactionStatus -> {
m_countryDao.findById(countryId);
return null;
});
}