我在Spring 3.2.11.RELEASE中使用Hibernate 4.3.11.Final。我很困惑,爲什麼我的緩存驅逐不起作用。我有這個成立於我的DAO ...爲什麼我的實體不會從我的二級緩存中被驅逐?
@Override
@Caching(evict = { @CacheEvict("main") })
public Organization save(Organization organization)
{
return (Organization) super.save(organization);
}
@Override
@Cacheable(value = "main")
public Organization findById(String id)
{
return super.find(id);
}
,這裏是我的Spring配置...
<cache:annotation-driven key-generator="cacheKeyGenerator" />
<bean id="cacheKeyGenerator" class="org.mainco.subco.myproject.util.CacheKeyGenerator" />
<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.myproject.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>
在下面的測試
然而,我的實體不獲取從緩存中逐出,我知道是因爲與「命中次數#3:」行,打印出「3」,而與「命中次數#2:」行打印出‘2’
private net.sf.ehcache.Cache m_cache
@Autowired
private net.sf.ehcache.CacheManager ehCacheManager;
@Before
public void setup()
{
m_cache = ehCacheManager.getCache("main");
m_transactionTemplate = new TransactionTemplate(m_transactionManager);
} // setup
...
@Test
public void testCacheEviction()
{
final String orgId = m_testProps.getProperty("test.org.id");
// Load the entity into the second-level cache
m_transactionTemplate.execute((TransactionCallback<Void>) transactionStatus -> {
m_orgSvc.findById(orgId);
return null;
});
final long hitCount = m_cache.getStatistics().getCacheHits();
System.out.println("hit count #1:" + hitCount);
m_transactionTemplate.execute((TransactionCallback<Void>) transactionStatus -> {
final Organization org = m_orgSvc.findById(orgId);
System.out.println("hit count:" + m_cache.getStatistics().getCacheHits());
org.setName("newName");
m_orgSvc.save(org);
return null;
});
// Reload the entity. This should not incur a hit on the cache.
m_transactionTemplate.execute((TransactionCallback<Void>) transactionStatus -> {
System.out.println("hit count #2:" + m_cache.getStatistics().getCacheHits());
final Organization newOrg = m_orgSvc.findById(orgId);
System.out.println("hit count #3:" + m_cache.getStatistics().getCacheHits());
return null;
});
什麼是正確的配置讓我來趕一個實體。來自我的第二樂隊VEL緩存
編輯:的CacheKeyGenerator類我在應用程序上下文中引用如下
public class CacheKeyGenerator implements KeyGenerator
{
@Override
public Object generate(final Object target, final Method method,
final Object... params) {
final List<Object> key = new ArrayList<Object>();
key.add(method.getDeclaringClass().getName());
key.add(method.getName());
for (final Object o : params) {
key.add(o);
}
return key;
}
}
定義的那樣,我沒有定義每個@Cacheable註釋的「鑰匙」,我更喜歡(少代碼)。但是,我不知道這是如何適用於CacheEviction。我認爲@CacheEvict註釋會使用相同的密鑰生成方案。
因爲我在我的應用程序上下文中包含了這個(從我的問題),'
Dave
您的密鑰生成器會爲兩種方法生成不同的密鑰,這又會導致密鑰不匹配,因此不會驅逐。打開調試日誌來驗證這一點。你會看到Spring緩存日誌,它會告訴你如何生成密鑰的邏輯錯誤。 – manish
我已經創建了一個[示例應用程序](https://github.com/manish-in-java/stackoverflow-questions/tree/master/35640220)向您展示我的答案有效。你可以下載並運行它作爲'mvn clean test'來查看所有的測試通過。有一個測試在那裏根據你的調用來檢查緩存狀態。我會建議你拿我的樣品,並添加你的代碼,沒有你的自定義密鑰生成器第一。如果您不對工作樣本進行任何更改,事情就應該起作用。然後插入密鑰生成器以查看錯誤的位置。 – manish