Perda de conexão Hibernate 3

Fala pessoal,

estou com um probleminha, já googlei e achei pessoas com o mesmo
problema, mas as soluções que parecem ter funcionado para mim não
funcionaram.

Tenho uma aplicação Hibernate 3, MySql. Quando a inicio ela
funciona tranquilamente, mas após algum tempo ociosa quando faço
os primeiros acessos recebo uma mensagem de falha de conexão com
o banco:

javax.servlet.ServletException: org.hibernate.exception.JDBCConnectionException: could not load an entity
...
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

Achei que pudesse ser o pool, e configurei-o diminuindo o timeout e
para que faça testes com as conexões periódicamente, desta forma:

<property name="c3p0.acquire_increment">1</property>
<property name="c3p0.min_size">2</property>
<property name="c3p0.max_size">20</property>
<property name="c3p0.timeout">120</property>
<property name="c3p0.idle_test_period">20</property>
<property name="c3p0.max_statements">100</property>

Estou inclusive informando o autoReconnect=true, em minha url do banco
de dados, mas mesmo assim tenho esse problema.

Tenho dúvidas se realmente o pool está fazendo os testes, ou se falta
alguma configuração.

Cara, o problema parece ser em seu controle de transacao. O Hibernate sempre que vai consultar a base de dados verifica se determinadas entities estao no cache, caso contrario ele vai ate a base de dados! Para isso ele faz um load na hibernate session, algo como session.load(entity, entityId);

Desconfio que seja isso!

Ate mais

Faz sentido o que vc disse, mas de que maneira poderai controlar as transações?

Estou fazendo isso de maneira explícita, e com o auto commit desligado.

Veja um exemplo de um load meu:

		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		Conteudo conteudo = (Conteudo) session.load(Conteudo.class, id);
		conteudo.getTitulo();
		
		session.getTransaction().commit();

Creio que o problema esteja ai mesmo. Veja que seu entity bean Conteudo com id =1 (apenas como exemplo), nao pertence a sessao do hibernate, já que voce nao tinha sessao aberta antes. O load só vai funcionar se seu entity estiver cacheado na sessao (mas voce ainda nao tem sessao aberta)! Entao, ao inves de utilizar load voce vai ter que executar uma query, nao tem jeito. Ai sim seu entity bean pertencerá ao contexto de persistencia e depois disso voce vai poder fazer sessio.load() em outras circunstancias!

Espero que de certo!

Ate

Tentei a solução e não obtive sucesso.

Então fiz o teste para ver se o método load() fazia a busca no banco de dados
caso a entidade não estivesse em cache, e ele realmente faz. Confirmei isso na
documentação do hibernate (e de quebra aprendi o método get() da session
que faz o mesmo que o método load, mas quando não encontra a entidade com o ID
especificado não retorna erro, e sim simplemente null).

Então continuei googleando e verifiquei a propriedade hibernate.connection.provider_class
que informa qual sistema de pool usar, e a informei explicitamente para o c3p0.

Despois disso verifiquei que o c3p0 nunca tinha sido iniciado, e que agora estava sendo.
Busquei na documentação do hibernate e nada é dito (ou pelo menos não encontrei)
sobre esta propriedade ser setada explicitamente para o c3p0, apenas diz que deve ser
informada se outro sistema de pool for utilizado.

Com isso meu problema se solucionou, e minha configuração ficou assim:

		<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>

		<property name="c3p0.acquire_increment">1</property>
		<property name="c3p0.min_size">3</property>
		<property name="c3p0.max_size">20</property>
		<property name="c3p0.timeout">240</property>
		<property name="c3p0.idle_test_period">60</property>
		<property name="c3p0.max_statements">100</property>

Na documentação do c3p0 pude notar que as propriedades que informei acima são todas
em segundos (e não em milésimos como achei várias pessoa dizendo na internet).

Agora o c3p0 está sendo iniciado, e está testando as conexões a cada 60 segundos, e as
descartando a cada 240 segundos. Talvez até seja meio exagero meu, mas continuarei
fazendo os testes para aumentar estes tempos e diminuir o custo da aplicação.

De qualquer modo valeu pela ajuda “Vini Fernandes”.

Espero ajudar outros… e valeu!!!