Ehcache + jpa nao funciona

17 respostas
D

Bom dia pessoal!

Seguinte, tem uns 3 dias que estou tentando fazer o meu ehcache funcionar com JPA do hibernate. O console do eclipse exibe apenas que o ehcache subiu, mas o tempo que coloco no ehcache.xml expira, ele NAO vai ao banco de dados e NAO exibe a sentenca sql que foi feita.

mesmo configurando pra

Sendo assim, alguem poderia me dar uma mao, por favor?

Nao sei mais o que fazer…

Att,

donatinho

17 Respostas

P

Isso não indica que está funcionando? O ehcache acessa objetos já carregados na memória, não deve ir ao banco.

Você checou no jmx-console do teu servidor se o cache está habilitado?

Você seguiu algum tutorial?

http://ehcache.org/documentation/hibernate.html
http://community.jboss.org/wiki/ConfigureEhcacheasaSecondLevelCache

D

Pozzo, mais um vez agradeco a atencao dispensada pela questao.

Bom, o que segui foram sites que encontrei pela internet, mas pelo visto estou configurando de forma errada.

Sendo assim, ratifico o meu problema.

Nao estou conseguinda fazer o ehcache do JPA funcionar com o hibernate

quando subo o jboss, aparece as seguintes linhas:

E obrigado pela informacao correta que tu colocou, realmente eu confundi as bolas.

Olha, pra ser sincero, nao estou sabendo é configurar essa tecnologia…

E olha que ja bati cabeca

:frowning:

P

Poste as seguintes informações:

Versão do Hibernate;

Nome e versão do container;

Um hbm.xml ou entidade (caso use annotation);

hibernate.cgf.xml ou persistence.xml;
D

hibernate : hibernate3.jar

Nome e versão do container : jboss-4.2.3.GA

Entidade:

package br.inf.aplicacao.alfa.vo;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Id;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Entity;

@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Tbparametro implements Serializable {
	@Id
	@Column(name="SG_PARAMETRO")
	private String sgParametro;

	@Column(name="VR_PARAMETRO")
	private String vrParametro;

	private static final long serialVersionUID = 1L;

	/**************************Contrutores *************************/
	public Tbparametro() {
		super();
	}
	
	public Tbparametro(String sgParametro, String vrParametro) {
		super();
		this.sgParametro = sgParametro;
		this.vrParametro = vrParametro;
	}

	/************************** Metodos publicos *************************/
	public String getSgParametro() {
		return this.sgParametro;
	}

	public void setSgParametro(String sgParametro) {
		this.sgParametro = sgParametro;
	}

	public String getVrParametro() {
		return this.vrParametro;
	}

	public void setVrParametro(String vrParametro) {
		this.vrParametro = vrParametro;
	}

}

DAO que contem a sentenca sql:

package br.inf.aplicacao.alfa.dao;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;

import org.hibernate.CacheMode;

import br.inf.aplicacao.alfa.interfaces.ParametroDaoIf;
import br.inf.aplicacao.alfa.vo.Tbparametro;


public class ParametroDao extends Dao implements ParametroDaoIf{

	
	public ParametroDao(EntityManager entityManager) {
		super(entityManager);
	}
	

	
	public String obterVlrParamPorSigla(String sgParametro) {			
		
		Tbparametro parametro = (Tbparametro)super.obterPorPK(Tbparametro.class, sgParametro);
		
		String vlrParametro = parametro != null ? parametro.getVrParametro() : null;
		return vlrParametro;
	}
	
	
	public List<Tbparametro> obterTdsParam(){
	     Query q = manager.createQuery("Select P from Tbparametro P ");
             q.setHint("org.hibernate.cacheable", true);
             q.setHint("org.hibernate.cacheMode", CacheMode.NORMAL);
             
        
        
		List<Tbparametro> listResultado = new ArrayList<Tbparametro>() ;
	
		
		try {			
			listResultado = q.getResultList();	
		
		} catch (NoResultException e) {  
			listResultado = null;
			
		}
		
	
		return listResultado;
	}

}

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">	
	<persistence-unit name="APLICACAO_HIBERNATE" transaction-type="JTA">
			
	<provider>org.hibernate.ejb.HibernatePersistence</provider>
	 	
	<jta-data-source>java:/AplicacaoDS</jta-data-source>
	
	<class>br.inf.aplicacao.alfa.vo.Tbparametro</class>
	
	<properties>
	
                <property name="hibernate.show_sql" value="true" /> 	
     	        <property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider"/>
	 	<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.EhCacheRegionFactory" />
	 	<property name="net.sf.ehcache.configurationResourceName" value="/ehcache.xml"/>
       	 
   	</properties> 
		
	</persistence-unit>
	
</persistence>

ehcache.xml

<ehcache>
	
	<diskStore path="java.io.tmpdir"/>
	
	<!-- Cache padrão. Elemento necessário -->
	<defaultCache maxElementsInMemory="200" 
				  eternal="false"
				  timeToIdleSeconds="600" 
				  timeToLiveSeconds="600" 
				  overflowToDisk="false" />
	<!-- 
		Este cache será realizado a cada 5 minutos
	 -->
	<cache name="br.inf.aplicacao.alfa.vo.Tbparametro"
		   maxElementsInMemory="100" 
		   eternal="false" 
		   timeToIdleSeconds="300"
		   timeToLiveSeconds="300" 
		   overflowToDisk="false" />
	
</ehcache>
P

Bom, vou supor que seja Hibernate 3.3. Adicione a seguinte linha no persistence.xml.

<property key="hibernate.cache.use_second_level_cache">true</property>

Você adicionou o jar do ecache no projeto, certo?

Comece fazendo uma pesquisa por id para ver se ele usa o cache. Depois uma por query.

D

Bom dia Pozzo!

Coloquei o property que tu havia pedido .

O jar do ehcache esta na raiz do projeto.

E ainda nao faz o cache…

:frowning:

complicado isso, nao?

D

Pozzo… consegui resolver o problema.

Fico muito agradecido pela sua ajuda, foi de fundamental relevancia para a solucao …

vou postar a solucao para que, se mais alguem passar pelo mesmo problema, consiga resolver rapidamente.

Att,

donatinho

D

Para configurar e fazer funcionar o ehcache com jpa no hibernate 3 e com jboss 4.2.3, oberseve abaixo como deve ser feito:

1 - arvore:

PERSISTENCE
  |_FONTES
       |_META-INF
            |_persistence.xml
       |_ehcache.xml
       |_br
            |_inf
                 |_aplicacao
                     |_alfa
                          |_vo
                               |_Tbparametro.class

2 - Configuracao do persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">	
	<persistence-unit name="APLICACAO_HIBERNATE" transaction-type="JTA">
		
	<provider>org.hibernate.ejb.HibernatePersistence</provider>
	 	
	<jta-data-source>java:/AplicacaoDS</jta-data-source>
	
	<class>br.inf.aplicacao.alfa.vo.Tbparametro</class>
	
	<properties>
	 	<property name="hibernate.show_sql" value="true" />
     	        <property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider"/>
	 	<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.EhCacheRegionFactory" />
	 	<property name="net.sf.ehcache.configurationResourceName" value="/ehcache.xml"/>
	 	<property name="hibernate.cache.use_second_level_cache" value="true" />
	 	<property name="hibernate.cache.region_prefix" value=""/>
  		
  		<property name="hibernate.cache.use_structured_entries"   value="true" />
      	        <property name="hibernate.cache.use_query_cache"          value="true" />
      	
      	  
   	</properties> 
		
	</persistence-unit>
	
</persistence>

3 - Configurar o seu vo para que consiga realizar o cache

package br.inf.aplicacao.alfa.vo;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Tbparametro implements Serializable {
	@Id
	@Column(name="SG_PARAMETRO")
	private String sgParametro;

	@Column(name="VR_PARAMETRO")
	private String vrParametro;

	private static final long serialVersionUID = 1L;

	/**************************Contrutuores *************************/
	public Tbparametro() {
		
	}
	
	public Tbparametro(String sgParametro, String vrParametro) {		
		this.sgParametro = sgParametro;
		this.vrParametro = vrParametro;
	}

	/************************** Metodos publicos *************************/
	public String getSgParametro() {
		return this.sgParametro;
	}

	public void setSgParametro(String sgParametro) {
		this.sgParametro = sgParametro;
	}

	public String getVrParametro() {
		return this.vrParametro;
	}

	public void setVrParametro(String vrParametro) {
		this.vrParametro = vrParametro;
	}

}

4 - Configuracao do ehcache.xml

<ehcache>
	
	<diskStore path="java.io.tmpdir"/>
	
	<!-- Cache padrão. Elemento necessário -->
	<defaultCache maxElementsInMemory="200" 
				  eternal="false"
				  timeToIdleSeconds="600" 
				  timeToLiveSeconds="600" 
				  overflowToDisk="false" />
	
	<!-- Este cache é usado se usar um cache de consultas sem definir um nome -->
    <cache name="org.hibernate.cache.StandardQueryCache"
    	   maxElementsInMemory="5"
    	   eternal="false"
    	   timeToLiveSeconds="120"
    	   overflowToDisk="true"/>
    
    <!-- Acompanha o timestamps das atualizações mais recentes de tabelas particular. -->
    <cache name="org.hibernate.cache.UpdateTimestampsCache"
    	   maxElementsInMemory="5000"
           eternal="true"
           overflowToDisk="true"/>
	
	<!-- 
		Este cache será realizado a cada 10 minutos
	 -->
	<cache name="br.inf.aplicacao.alfa.vo.Tbparametro"
		   maxElementsInMemory="100" 
		   eternal="false" 
		   timeToIdleSeconds="600"
		   timeToLiveSeconds="600" 
		   overflowToDisk="false" />
	
</ehcache>

5 - Subir o Jboss e verificar se as linhas abaixo aparecem:

.
.
.
11:55:53,084 INFO  [SettingsFactory] Second-level cache: enabled
11:55:53,084 INFO  [SettingsFactory] Query cache: enabled
11:55:53,084 INFO  [SettingsFactory] Cache provider: net.sf.ehcache.hibernate.EhCacheProvider
11:55:53,084 INFO  [SettingsFactory] Optimize cache for minimal puts: disabled
11:55:53,084 INFO  [SettingsFactory] Structured second-level cache entries: enabled
11:55:53,084 INFO  [SettingsFactory] Query cache factory: org.hibernate.cache.StandardQueryCacheFactory
.
.
.
11:55:54,100 WARN  [CacheFactory] read-only cache configured for mutable class: br.inf.portalfiscal.aplicacao.vo.Tbparametro
.
.
.

Assim, o ehcache com o JPA para o hibernate 3 no jboss 4.2.3 ira funcionar…

Valeu Pozzo!!! Tua ajuda foi fundamental para a solucao deste problema

see ya

donatinho

F

Posso tentar essa config ai no tomcat q funciona ? ou tem que colocar outros jar’s ?

P

Cara, acho que você pode usar a mesma configuração. Não tem nada de especifico do JBoss. Só vai ter que configurar um data source no tomcat:

<jta-data-source>java:/AplicacaoDS</jta-data-source>

Tem também algumas boas práticas que o pessoal do Ehcache recomenda para o Tomcat:

http://ehcache.org/documentation/tomcat.html
F

Tentei fazer ontem…mas não deu certo…não acusa erro, não mostra nada…o JPA simplesmente funciona normal…
Como eu sei q o cache esta no ar ? O Hibernate log algo ?
Alguma dica ?
Vou olhar esse link ai…
Valeu

M

Donatinho, bom dia beleza ? Cara, segui seu exemplo mas o cache aqui não funciona. No log do Jboss mostra as regions que foram encontradas declaradas no arquivo ehcache mas não acho alguma linha no console dizendo que a minha entidade foi cacheada.
Sendo assim, na segunda vez que executo a minha consulta, vejo o sql sendo executado no console normalmente.
Sabe o que pode estar acontecendo ?

Abraço

D

bom dia!

Cara, se voce verificar o item 5 do post do dia 28/04/2010 12:59:16 tu vera que este log é que diz que o cache esta habilitado. Contudo, apenas as entidades que forem read-only que aparecerao tambem no log.

Lembrando que, por ser cache, quando executar o mesmo, ele nao aparecera no console (acredito eu).

Uma coisa, eu estava testando o cache de forma assim. Tipo, subia a aplicacao e dava um update na base de dados. Assim via se o cache estava funcionando, apos passar o tempo estabelecido, a aplicacao pegava o valor informado atualizado no banco.

A minha aplicacao funciona o cache.

Espero ter ajudado.

donatinho

M

Obrigado pela resposta donatinho !
No caso eu tenho uma entity dessa forma

@Unique(field=descricao , keyMessageError=indicador.msg_28)

@MappedSuperclass

@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)

public class Indicador implements IGenericBean {

Supostamente deveria existir uma linha no console
parecida com a que você citou

CacheFactory] read-only cache configured for mutable class: br.com.consist.solution.flexsi.entity.Indicador.

No entanto, não aparece nada referente a entity Indicador.java e sempre é executado o sql quando executo a query novamente. O cache está habilitado mas não sei se de fato está funcionando.

Bom, vou continuar olhando o que pode ser !
Novamente, muito obrigado pelo retorno donatinho !
Abraço

E

Boa noite caros, também estou tendo problemas para colocar o ehcache para funcionar (query cache) na minha aplicação web. Acho que está faltando alguma configuração específica, pois com a configuração atual, ao rodar uma classe java simples com um método main, o resultado mostra que o cache está funcionando corretamente. Nesta classe executo uma query a primeira vez

cidades = em.createQuery("select c from Cidade c").setHint("org.hibernate.cacheable", true).getResultList();

em seguida executo um update via jdbc na entidade, e por último executo a query novamente. O resultado é o esperado, a query esta sendo cacheada pois o
resultado da segunda chamada é o mesmo da primeira, apesar de 1 dos objetos ter sido atualizado via jdbc…

Porém na aplicação web não ocorre o esperado. Esta mesma query encontra-se em um método de um EJB, e é invocada ao carregar uma página. O teste que estou fazendo é simples: carrego a página e vejo a lista, em seguida faço update no banco de dados e recarrego a página, que me mostra os registros alterados.

Acho que o cache está durando somente durante a vida do EntityManager. Ao fazer um novo teste na classe citada anteriormente, porém fechando o EntityManager via em.close(), e obtendo uma nova instância para 2 execução da query, o resultado mostra os registros alterados conforme o update via jdbc…
Bem espero ter sido claro hehehe, grato por qualquer ajuda.

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="dho-jee6-ejbPU" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>mySql-Dho-Ds</jta-data-source>
        <class>br.com.dho.model.entity.Cidade</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>

        <properties>
            <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/>
            <property name="hibernate.cache.use_second_level_cache" value="true"/>
            <property name="hibernate.cache.use_query_cache" value="true"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
        </properties>

   </persistence-unit>
</persistence>

[]s.

E

Bom dia caros, consegui resolver o problema anotando as classes de entidade para serem cacheadas, pensei que fosse necessário anotá-las apenas para cachear os objetos obtidos por find, lazyload ou outro mecanismo que não fosse Query. Descobri também que no meu primeiro experimento em que eu achava que o 2nd level cache estava funcionando, na verdade era o 1st level cache, por isso ao fechar a sessão ( em.close() ), o resultado vinha conforme o update, pois o 2nd level não estava habilitado devido não ter anotado as classes de entidade. Outra coisa, se vc não criar o arquivo ehcache.xml com suas configurações, o arquivo ehcache-failsafe.xml existente dentro do jar do ehcache é utilizado. []'s.

R

Galera,

Configurei como citado pelo donatinho, verifiquei meu Jboss e ele subiu com as linhas que indicam o cache no ar, mapeei uma entidade como eternal=“true” e a estrategia como READ_ONLY, porém, todas as vezes que faço o select ele printa a consulta no console, logo acredito que o cache não está funcionando.

Porém, o metodo de pegar a lista é atraves de uma criteria, onde ele me traz uma lista dessa entidade, que é sempre a mesma, pois se trata de uma lista de Estados Brasileiros, será que devo cachear a query?

Alguém tem alguma dica de como testar isso?

PS: O meu entendimento está correto né? Uma vez eternal e read only, ele não deveria mais ir ao banco apos a primeira consuta certo?
Outra coisa, ao eu der um shutdown no Jboss o cache é limpo, e ao subir de novo ele tera que refazer o cache, isso é correto?

Criado 27 de abril de 2010
Ultima resposta 16 de set. de 2010
Respostas 17
Participantes 6