Sto usando Hibernate 4.3.11.Final con Spring 3.2.11.RELEASE. Sono confuso sul motivo per cui il mio sfratto della cache non funziona. Ho questo set up della mia DAO ...Perché la mia entità non è sfrattata dalla mia cache di secondo livello?
@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);
}
ed ecco la mia primavera config ...
<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>
Eppure, nel test di seguito, il mio soggetto non sta ottenendo sfrattato dalla cache, che so, perché la linea con “numero di passaggi # 3:” stampa i “3”, mentre la linea con "numero di passaggi # 2:” stampa out ‘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;
});
Qual è la giusta configurazione per permettermi di sfrattare un'entità. dal mio secondo-le cache di vel
Edit:? La classe CacheKeyGenerator ho fatto riferimento nel mio contesto di applicazione è definito di seguito
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;
}
}
Come tale non c'è bisogno di definire una “chiave” per ciascuna annotazione @Cacheable che ho preferisci (meno codice). Tuttavia, non so come questo si applica a CacheEviction. Pensavo che l'annotazione @CacheEvict avrebbe utilizzato lo stesso schema di generazione di chiavi.
È possibile includerlo nel contesto dell'applicazione (dalla mia domanda), '
Dave
Il generatore di chiavi genera chiavi diverse per i due metodi, che di nuovo determinano una mancata corrispondenza delle chiavi e quindi nessuno sfratto. Attiva i log di debug per verificarlo. Verranno visualizzati i registri di memorizzazione nella cache di Spring che mostreranno l'errore logico nel modo in cui si genera la chiave. – manish
Ho creato una [applicazione di esempio] (https://github.com/manish-in-java/stackoverflow-questions/tree/master/35640220) per dimostrare che la mia risposta funziona. Puoi scaricarlo ed eseguirlo come 'mvn clean test' per vedere tutti i test che passano. C'è un test in là per controllare lo stato della cache in base alle tue chiamate. Ti suggerirò di prendere il mio campione e aggiungervi il codice, senza prima creare il tuo generatore di chiavi personalizzato. Le cose dovrebbero funzionare se non si apportano modifiche al campione funzionante. Quindi collegare il generatore di chiavi per vedere dove si trova l'errore. – manish