Limpar cache de segundo nível

3 respostas
D

Bom dia Pessoal!

Estou com o seguinte problema, tenho uma aplicação com JPA com hibernate 3 + ehcache. Está tudo funcionando corretamente, porém uma outra aplicação acessa o mesmo banco de dados, e todas as alterações realizada por esta outra aplicação não fica visível na minha pois estou utilizando o cache de segundo nível do ehcache, o que faz com que meu cache fique inconsistente.

Estou precisando de algum método que eu possa implementar para limpar o cache de segundo nível do ehcache toda vez que a outra aplicação fizer alguma alteração no banco. Esta outra aplicação utiliza JDBC.

3 Respostas

D

Consegui resolver :idea: , como muitas pessoas também procuraram e não havia a resposta em nenhum lugar, estou postando a forma que consegui resolver o problema, talvez ajude outras pessoas...

Estou usando JPA, então criei o seguinte método na minha factory:
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JPAUtil {
	
	private static EntityManagerFactory factory = Persistence
			.createEntityManagerFactory("FerramentaWeb");

	public EntityManager getEntityManager() {
		return factory.createEntityManager();
	}
	
	// Este foi o método que inclui!
	public void limpaCache(){
		factory.getCache().evictAll();
	}

}
Agora sempre que eu quiser limpar o meu cache, basta eu usar este método:
new JPAUtil().limpaCache();

O evict pode ser em apenas uma classe também, seria mais eficiente no caso de precisar atualizar parte do cache, infelizmente não é o meu caso... :?

Espero ter ajudado!

Diogo :shock:

D
Galera, me surgiu outro problema. Tenho a seguinte classe:
@Entity
@Table(name = "tblFormWeb")
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class TblFormWeb implements Serializable, InterfaceValidaAtributo {
	private static final long serialVersionUID = 1L;
	
	@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
	@OneToMany(mappedBy="formWeb")
	@OrderBy("cvOrd")
	private List<TblDetFormWeb> detFormWeb;
	
	public List<TblDetFormWeb> getDetFormWeb() {
		return detFormWeb;
	}

	public void setDetFormWeb(List<TblDetFormWeb> detFormWeb) {
		this.detFormWeb = detFormWeb;
	}

	@Id
	private Integer cvCodFormWeb;
...

Consigo limpar o cache da classe com o comando mencionado acima, porém ele não limpa o cache do meu Join detFormWeb...
Alguém sabe como resolver isso?

D

Consegui resolver…
Estou postando a solução para caso alguém tenha o mesmo problema…

Na minha classe public class JPAUtil inclui o seguinte método:

public void limpaCacheManager(String region){
	List<CacheManager> allCacheManagers = CacheManager.ALL_CACHE_MANAGERS;
	for (CacheManager cacheManager : allCacheManagers) {
		Cache cache = cacheManager.getCache(region);
		EhCache ehcache = new EhCache(cache);
		if (ehcache != null) {					
			ehcache.clear();				
		}
	}
}

Na minha entidade fiz a seguinte mudança:

@Entity
	@Table(name = "tblFormWeb")
	@Cacheable
	@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
	public class TblFormWeb implements Serializable, InterfaceValidaAtributo {
		private static final long serialVersionUID = 1L;
		
		// Inclui aqui o comando "region"!
		@Cache(region="cacheFormWeb", usage = CacheConcurrencyStrategy.READ_WRITE)
		@OneToMany(mappedBy="formWeb")
		@OrderBy("cvOrd")
		private List<TblDetFormWeb> detFormWeb;
		
		public List<TblDetFormWeb> getDetFormWeb() {
			return detFormWeb;
		}
	
		public void setDetFormWeb(List<TblDetFormWeb> detFormWeb) {
			this.detFormWeb = detFormWeb;
		}
	
		@Id
		private Integer cvCodFormWeb;

E para limpar o cache, eu chamo o método passando a região por parâmetro:

jpa.limpaCacheManager("cacheFormWeb");

Espero ter ajudado… :wink:

Criado 19 de setembro de 2011
Ultima resposta 7 de out. de 2011
Respostas 3
Participantes 1