VRaptor + Spring - Não fecha conexões

3 respostas
L

Boa tarde.

Caros, estou passando por um probleminha chaaaaaaato com o vraptor + spring. A princípio na minha aplicação, estou usando o Transaction Manager do spring, sem C3P0 nem nada. Depois de um tempo usando a aplicação ela para de funcionar e começa a dar “Too many connections” na hora de abrir as sessões do hibernate.

Tentei colocar o C3P0 para gerenciar as conexões, mas mesmo assim não funciona e o mesmo problema permanece, só que agora a mensagem do c3p0 “pool is already maxed out”, ou seja, basicamente a mesma coisa do primeiro caso.

Estou usando uma classe ComponentFactory para criar as sessões para o spring:

package br.com.mailing.component;

import java.lang.reflect.Method;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import net.vidageek.mirror.dsl.Mirror;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.SessionFactoryUtils;

import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.ioc.ComponentFactory;
import br.com.caelum.vraptor.ioc.RequestScoped;
import br.com.caelum.vraptor.proxy.MethodInvocation;
import br.com.caelum.vraptor.proxy.Proxifier;
import br.com.caelum.vraptor.proxy.SuperMethod;

@Component
public class CriadorDeSession implements ComponentFactory<Session> {
	private final SessionFactory factory;
	private final Proxifier proxifier;
	private Session session;

	public CriadorDeSession(SessionFactory factory, Proxifier proxifier) {
		this.factory = factory;
		this.proxifier = proxifier;
	}

	@PostConstruct
	public void abre() {
		this.session = proxifier.proxify(Session.class,
				new MethodInvocation<Session>() {
					public Object intercept(Session proxy, Method method,
							Object[] args, SuperMethod superMethod) {
						Session sessionDoSpring = SessionFactoryUtils
								.doGetSession(factory, true);
						return new Mirror().on(sessionDoSpring).invoke()
								.method(method).withArgs(args);
					}
				});
	}

	public Session getInstance() {
		return this.session;
	}

	@PreDestroy
	public void fecha() {
		this.session.close();
	}
}

É como se ele abrisse as conexões mas não fechasse ou não devolvesse para o pool. Alguém sabe o que se passa? Obrigado.

3 Respostas

Lucas_Cavalcanti

dentro do código do proxy vc tá sempre abrindo uma session nova. A idéia é só abrir se ela ainda não tiver sido abertaa…

guarde a variavel sessionDoSpring como field do CriadorDeSession e só crie se ele estiver nulo

L
Lucas Cavalcanti:
dentro do código do proxy vc tá sempre abrindo uma session nova. A idéia é só abrir se ela ainda não tiver sido abertaa...

guarde a variavel sessionDoSpring como field do CriadorDeSession e só crie se ele estiver nulo

Opa Lucas blezinha!

Agora deixei dessa forma:

package br.com.mailing.component;

import java.lang.reflect.Method;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import net.vidageek.mirror.dsl.Mirror;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.SessionFactoryUtils;

import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.ioc.ComponentFactory;
import br.com.caelum.vraptor.proxy.MethodInvocation;
import br.com.caelum.vraptor.proxy.Proxifier;
import br.com.caelum.vraptor.proxy.SuperMethod;

@Component
public class CriadorDeSession implements ComponentFactory<Session> {
	private final SessionFactory factory;
	private final Proxifier proxifier;
	private Session session;
	private Session sessionDoSpring;

	public CriadorDeSession(SessionFactory factory, Proxifier proxifier) {
		this.factory = factory;
		this.proxifier = proxifier;
	}

	@PostConstruct
	public void abre() {
		this.session = proxifier.proxify(Session.class,
				new MethodInvocation<Session>() {
					public Object intercept(Session proxy, Method method,
							Object[] args, SuperMethod superMethod) {
						if(sessionDoSpring == null) {
							sessionDoSpring = SessionFactoryUtils.doGetSession(factory, true);
						}
						return new Mirror().on(sessionDoSpring).invoke()
								.method(method).withArgs(args);
					}
				});
	}

	public Session getInstance() {
		return this.session;
	}

	@PreDestroy
	public void fecha() {
		this.session.close();
	}
}

Eu estava imaginando que aquela sessionDoSpring morria com o método e que a única que ficava aberta era a session da classe, e mesmo assim, essa seria fechada no método fecha(). E não estava entendendo como estava abrindo tanta session. Agora até o C3P0 está se comportando normalmente, pois antes, mesmo aguardando o timeout das conexões de acordo com a configuração do c3p0 as conexões não eram liberadas.

Talvez tenha outras pessoas com este problema, pois como peguei essa classe da apostila FJ28, creio que outras pessoas devam estar passando por isso também.

Muito obrigado. Vou monitorar a aplicação por enquanto e ver o que acontece. Vlw

Lucas_Cavalcanti

no fecha seria melhor:

if (sessionDoSpring != null)
   sessionDoSpring.close();

senão vc vai abrir uma session só pra fechar :wink:

Criado 1 de agosto de 2011
Ultima resposta 1 de ago. de 2011
Respostas 3
Participantes 2