[RESOLVIDO] Relacionamento Hibernate + Vraptor

Tenho um grupo de usuário a qual tem um supervisor criei um relacionamento @ManyToOne porem quando vou realizar o inserte no banco ele não insere o id do usuário e assim não faz o meu relacionamento
Segue abaixo a classe usuário:

[code]
@Entity
public class Grupo {
@Id
@GeneratedValue
private Long id;
private String nomeGrupo;
@ManyToOne (targetEntity = Usuario.class, fetch = FetchType.LAZY)
@ForeignKey(name=“fk_usuario_Grupo”)
private Usuario supervisor;

/**
 * @return the id
 */
public Long getId() {
	return id;
}
/**
 * @param id the id to set
 */
public void setId(Long id) {
	this.id = id;
}
/**
 * @return the nomeGrupo
 */
public String getNomeGrupo() {
	return nomeGrupo;
}
/**
 * @param nomeGrupo the nomeGrupo to set
 */
public void setNomeGrupo(String nomeGrupo) {
	this.nomeGrupo = nomeGrupo;
}
/**
 * @return the supervisor
 */
public Usuario getSupervisor() {
	return supervisor;
}
/**
 * @param supervisor the supervisor to set
 */
public void setSupervisor(Usuario supervisor) {
	this.supervisor = supervisor;
}

}[/code]

David, boa tarde!

Você poderia postar os códigos do controller e do DAO?

Eu estou achando que o problema é que você não está setando o atributo supervisor

GrupoDAO

@Component
public class GrupoDao {

	private final Session session;

	public GrupoDao() {
		this.session = CreateSession.getSession();
	}

	// Salva Grupo e depois comita no banco.
	public void salvar(Grupo grupo) {
		Session session = CreateSession.getSession();
		Transaction tx = session.beginTransaction();
		session.save(grupo);
		tx.commit();
		System.out.println("############# Cria Grupo no Banco ##############");
	}

	// Listagem a qual vai ser usada no controller
	@SuppressWarnings("unchecked")
	public List<Grupo> listaTudo() {
		return this.session.createCriteria(Grupo.class).list();
	}

	// Carregar Grupo para a sessão
	public Grupo carregar(Long id) {
		return (Grupo) this.session.load(Grupo.class, id);
	}

	// Atualiza Grupo e depois comita no banco.
	public void atualizar(Grupo grupo) {
		Transaction tx = session.beginTransaction();
		this.session.update(grupo);
		tx.commit();
		System.out.println("############# Atualizou Grupo no Banco ##############");
	}

	// Deleta Grupo e depois comita no banco.
	public void remover(Grupo grupo) {
		Transaction tx = session.beginTransaction();
		this.session.delete(grupo);
		tx.commit();
		System.out.println("############# Removeu Grupo no Banco ##############");
	}
	
	//Buscar Dispositivos
	@SuppressWarnings("unchecked")
	public List<Grupo> busca(String nomeGrupo) {
		return session.createCriteria(Grupo.class)
				.add(Restrictions.ilike("nomeGrupo", nomeGrupo, MatchMode.ANYWHERE))
				.list();
	}
}

GrupoController

[code]
@Resource
public class GrupoController {

private final UsuarioDao usuarioDao;
private GrupoDao dao;
private final Result result;
private final Validator validator;

public GrupoController(GrupoDao dao, Result result, Validator validator, UsuarioDao usuarioDao) {
	this.dao = dao;
	this.result = result;
	this.validator = validator;
	this.usuarioDao = usuarioDao;
}

// Lista os grupos
public List<Grupo> lista() {
	return dao.listaTudo();
}

// Lista os Usuario
public List<Usuario> listaUsuario() {
	return usuarioDao.listaTudo();
}

// Cadastrar Grupos
public void adicionar(Grupo grupo) {
	GrupoDao dao = new GrupoDao();
	dao.salvar(grupo);
	result.use(Results.logic()).redirectTo(GrupoController.class).lista();
}

// Alterar Grupos
public void alterar(Grupo grupo) {
	dao.atualizar(grupo);
	result.use(Results.logic()).redirectTo(GrupoController.class).lista();
}

// Editar Grupos
public Grupo editar(Long id) {
	return dao.carregar(id);
}

// Deletar Grupos
public void remover(Long id) {
	Grupo produto = dao.carregar(id);
	dao.remover(produto);
	result.use(Results.logic()).redirectTo(GrupoController.class).lista();
}

//Buscar Grupos
public List<Grupo> busca(String nomeGrupo) {
	result.include("nomeGrupo", nomeGrupo);
	return dao.busca(nomeGrupo);
}

public void cadastro() {
}

}[/code]

Então, vamos mexer em algumas coisinhas.
O VRaptor é poderosíssimo e tem alguns recursos que você pode utilizar, tais como a injeção de dependências.

Por exemplo: Criar um DAO genérico e não se preocupar mais com código repetido, mas sim com código específico:

public class GenericDAO<T> {
	private final Class<T> classe;
	private final Session session;

	public GenericDAO(Session session, Class<T> classe) {
		this.session = session;
		this.classe = classe;
	}

	public void saveOrUpdate(T obj) throws HibernateException {
		try {
			this.session.getTransaction().begin();
			this.session.saveOrUpdate(obj);
			this.session.getTransaction().commit();
		} catch (HibernateException e) {
			this.session.getTransaction().rollback();
			throw e;
		}
	}

	public void delete(T obj) throws HibernateException {
		try {
			this.session.getTransaction().begin();
			this.session.delete(obj);
			this.session.getTransaction().commit();
		} catch (HibernateException e) {
			this.session.getTransaction().rollback();
			throw e;
		}
	}

	public void delete(Long id) throws HibernateException {
		this.delete(this.get(id));
	}

	public T get(Long id) throws HibernateException {
		T obj = classe.cast(this.session.createCriteria(classe)
				.add(Restrictions.idEq(id)).uniqueResult());
		Hibernate.initialize(obj);
		return obj;
	}

	@SuppressWarnings("unchecked")
	public List<T> list() throws HibernateException {
		return this.session.createCriteria(classe).list();
	}
}

Dessa forma, seu GrupoDAO fica um pouco melhor:

@Component
public class GrupoDAO {

	private final Session session;
	private GenericDAO<Grupo> genericDAO;

	public GrupoDAO(Session session) {
		this.session = session;
		genericDAO = new GenericDAO<Grupo>(session, Grupo.class);
	}

	public void saveOrUpdate(Grupo obj) throws HibernateException {
		genericDAO.saveOrUpdate(obj);
	}

	public void delete(Grupo obj) throws HibernateException {
		genericDAO.delete(obj);
	}

	public void delete(Long id) throws HibernateException {
		genericDAO.delete(id);
	}

	public Grupo get(Long id) throws HibernateException {
		return genericDAO.get(id);
	}

	public List<Grupo> list() throws HibernateException {
		return genericDAO.list();
	}

	// Por ser mais específico, pode ficar dessa forma. Embora exista um jeito
	// melhor.
	// Buscar Dispositivos
	@SuppressWarnings("unchecked")
	public List<Grupo> busca(String nomeGrupo) {
		return session
				.createCriteria(Grupo.class)
				.add(Restrictions.ilike("nomeGrupo", nomeGrupo,
						MatchMode.ANYWHERE)).list();
	}
}

Mas para isso, você vai precisar fazer um ComponentFactory de Session e de SessionFactory:

@Component
public class SessionProvider implements ComponentFactory<Session> {

	private Session session;

	public SessionProvider(SessionFactory sessionFactory) {
		session = sessionFactory.openSession();
	}

	@Override
	public Session getInstance() {
		return session;
	}

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

}

@Component
@ApplicationScoped
public class SessionFactoryProvider implements ComponentFactory<SessionFactory> {

	private SessionFactory sessionFactory;

	public SessionFactoryProvider() {
		AnnotationConfiguration configuration = new AnnotationConfiguration();
		configuration.setProperty("hibernate.connection.username", "root");
		configuration.setProperty("hibernate.connection.password", "");
		configuration.setProperty("hibernate.connection.url", "jdbc:mysql://localhost:3306/banco");

		configuration.setProperty("hibernate.connection.driver_class",
				"com.mysql.jdbc.Driver");
		configuration.setProperty("hibernate.dialect",
				"org.hibernate.dialect.MySQL5InnoDBDialect");
		configuration.setProperty("hibernate.hbm2ddl.auto", "update");
		configuration.setProperty("show_sql", "false");
		configuration.setProperty("format_sql", "false");

		configuration.setProperty("hibernate.connection.provider_class",
				"org.hibernate.connection.C3P0ConnectionProvider");
		configuration.setProperty("hibernate.c3p0.acquire_increment", "2");
		configuration.setProperty("hibernate.c3p0.timeout", "25200");
		configuration.setProperty("hibernate.c3p0.min_size", "2");
		configuration.setProperty("hibernate.c3p0.max_size", "10");
		configuration.setProperty("hibernate.c3p0.max_statements", "0");

		configuration.setProperty("hibernate.generate_statistics", "false");

		configuration.addAnnotatedClass(Grupo.class);
		configuration.addAnnotatedClass(Usuario.class);

		this.sessionFactory = configuration.buildSessionFactory();
	}

	@Override
	public SessionFactory getInstance() {
		return this.sessionFactory;
	}

	@PreDestroy
	public void destroy() {
		this.sessionFactory.close();
	}

}

Agora, no seu controller, você não precisa mais se preocupar em instanciar o costrutor:

Agora quanto ao problema em específico, você vai precisar receber o id do usuário e setar o supervisor, no seu controller…

@Resource
public class GrupoController {

	private final UsuarioDAO usuarioDAO;
	private final GrupoDAO grupoDAO;
	private final Result result;

	public GrupoController(GrupoDAO grupoDAO, Result result,
			UsuarioDAO usuarioDAO) {
		this.grupoDAO = grupoDAO;
		this.result = result;
		this.usuarioDAO = usuarioDAO;
	}

	// Lista os grupos
	public List<Grupo> lista() {
		return grupoDAO.list();
	}

	// Lista os Usuario
	public List<Usuario> listaUsuario() {
		return usuarioDAO.list();
	}

	// Cadastrar Grupos
	public void adicionar(Grupo grupo, Long supervisorId) {
		grupo.setSupervisor(usuarioDAO.get(supervisorId));

		grupoDAO.saveOrUpdate(grupo);
		result.redirectTo(GrupoController.class).lista();
	}

	// Alterar Grupos
	public void alterar(Grupo grupo) {
		grupoDAO.saveOrUpdate(grupo);
		result.redirectTo(GrupoController.class).lista();
	}

	// Editar Grupos
	public Grupo editar(Long id) {
		return grupoDAO.get(id);
	}

	// Deletar Grupos
	public void remover(Long id) {
		grupoDAO.delete(id);
		result.redirectTo(GrupoController.class).lista();
	}

	// Buscar Grupos
	public List<Grupo> busca(String nomeGrupo) {
		result.include("nomeGrupo", nomeGrupo);
		return grupoDAO.busca(nomeGrupo);
	}

	public void cadastro() {
	}

}

E repara que você pode fazer o mesmo com o UsuarioDAO:

@Component
public class UsuarioDAO {
	private GenericDAO<Usuario> genericDAO;

	public UsuarioDAO(Session session) {
		genericDAO = new GenericDAO<Usuario>(session, Usuario.class);
	}

	public void saveOrUpdate(Usuario obj) throws HibernateException {
		genericDAO.saveOrUpdate(obj);
	}

	public void delete(Usuario obj) throws HibernateException {
		genericDAO.delete(obj);
	}

	public void delete(Long id) throws HibernateException {
		genericDAO.delete(id);
	}

	public Usuario get(Long id) throws HibernateException {
		return genericDAO.get(id);
	}

	public List<Usuario> list() throws HibernateException {
		return genericDAO.list();
	}
}

Rafael e extremamente necessário eu criar o SessionProvider e o SessionFactoryProvider !?

necessário não é, mas é melhor…

quando vc manda salvar o grupo, o id do usuário está preenchido?

Estou perguntando pois tenho um CreateSession a qual ler o Hibernate.cfg.xml

public class CreateSession {

	public static Session getSession() {
		//Cria a configuração.
		AnnotationConfiguration configuration = new AnnotationConfiguration();
		//Lê o Hibernate.cfg.xml
		configuration.configure();
		SessionFactory factory = configuration.buildSessionFactory();
		Session session = factory.openSession();
		return session;
	}

}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!-- Configuração Banco do Banco -->
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">123456</property>
		<property name="hibernate.connection.url">jdbc:mysql://localhost/futura</property>
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
		<property name="hibernate.show_sql">true</property>
		<property name="hibernate.format_sql">true</property>
		<property name="hibernate.hbm2ddl.auto">update</property>
		<property name="hibernate.hbm2ddl.auto">commit</property>
		<property name="connection.pool_size">2</property>

		<!-- configuration pool via c3p0 -->
		<property name="c3p0.acquire_increment">2</property>
		<property name="c3p0.idle_test_period">100</property> <!-- seconds -->
		<property name="c3p0.max_size">10</property>
		<property name="c3p0.max_statements">0</property>
		<property name="c3p0.min_size">2</property>
		<property name="c3p0.timeout">25200</property> <!-- seconds -->
		<!-- DEPRECATED very expensive property name="c3p0.validate> -->

		<!-- Entidades -->
		<mapping class="ws.futuranet.modelo.Usuario" />
		<mapping class="ws.futuranet.modelo.Dispositivo" />
		<mapping class="ws.futuranet.modelo.Cliente" />
		<mapping class="ws.futuranet.modelo.Grupo" />

	</session-factory>
</hibernate-configuration>

E lucas por enquanto ainda estou digitando o id do usuário na mão
Mais pretendo passar isso via um parâmetro vindo de um pop - up

cuidado: você está abrindo a Session, mas não está fechando… isso vai causar vazamento de conexões e sua aplicação vai parar de funcionar depois de um tempo…

bom, se vc tá passando mesmo o id do usuário antes de salvar o grupo, não tem pq ele não salvar isso no banco.

Seguir o conselho do rafael e criei o genericDAO porem ele da o seguinte erro no console:

org.hibernate.TransactionException: Transaction not successfully started
	org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:131)
	br.com.caelum.vraptor.util.hibernate.HibernateTransactionInterceptor.intercept(HibernateTransactionInterceptor.java:50)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54)
	br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:23)
	br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58)
	br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)

E também pude observar que na url do projeto tanto o id quanto o nome do grupo estão setados corretamente

http://localhost:8080/futura/grupo/adicionar?grupo.nomeGrupo=Teste&grupo.supervisor=1

E como poderia fechar essa conexão do session ?

faz o seguinte, apague a sua classe CreateSession e coloque essas linhas no seu web.xml:

<context-param>
    <param-name>br.com.caelum.vraptor.packages</param-name>
    <param-value>br.com.caelum.vraptor.util.hibernate</param-value>
</context-param>

(se já tiver essa configuração de packages, só acrescente o pacote do hibernate)

e em todos os lugares onde estava usando esse CreateSession, receba a session no Construtor (se for um @Component ou algo do tipo)

o VRaptor vai se encarregar de cuidar da session pra vc.

Não precisa abrir transações no seu código, pq o VRaptor vai fazer isso pra vvc tb.

ah, vc passou o parâmetro: grupo.supervisor=1 , mas se vc quer setar o id do supervisor, vc precisa passar:

grupo.supervisor.id=1

Fiz todos esses passo consigo realizar todas as operações no hibernate porem ainda fica dando o seguinte erro que nao tenho ideia do que pode ser !

17:03:51,540 DEBUG [AbstractFlushingEventListener] processing flush-time cascades 17:03:51,540 DEBUG [AbstractFlushingEventListener] dirty checking collections 17:03:51,541 DEBUG [AbstractFlushingEventListener] Flushed: 0 insertions, 0 updates, 1 deletions to 1 objects 17:03:51,541 DEBUG [AbstractFlushingEventListener] Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections 17:03:51,542 DEBUG [Printer ] listing entities: 17:03:51,542 DEBUG [Printer ] ws.futuranet.modelo.Grupo{id=4, nomeGrupo=Teste, supervisor=null} 17:03:51,542 DEBUG [AbstractBatcher ] about to open PreparedStatement (open PreparedStatements: 0, globally: 0) 17:03:51,542 DEBUG [SQL ] delete from Grupo where id=? Hibernate: delete from Grupo where id=? 17:03:51,542 DEBUG [AbstractBatcher ] Executing batch size: 1 17:03:51,542 DEBUG [AbstractBatcher ] about to close PreparedStatement (open PreparedStatements: 1, globally: 1) 17:03:51,591 DEBUG [JDBCTransaction ] committed JDBC Connection 17:03:51,591 DEBUG [ConnectionManager ] aggressively releasing JDBC connection 17:03:51,591 DEBUG [ConnectionManager ] releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)] 16/01/2012 17:03:51 org.apache.catalina.core.StandardWrapperValve invoke GRAVE: Servlet.service() for servlet [default] in context with path [/futura] threw exception org.hibernate.TransactionException: Transaction not successfully started at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:131) at br.com.caelum.vraptor.util.hibernate.HibernateTransactionInterceptor.intercept(HibernateTransactionInterceptor.java:50) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:83) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:48) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ExceptionHandlerInterceptor.intercept(ExceptionHandlerInterceptor.java:71) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:69) at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54) at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:54) at br.com.caelum.vraptor.core.EnhancedRequestExecution.execute(EnhancedRequestExecution.java:23) at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92) at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:58) at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:539) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662)

Como se apos realizar a operação ele não enxergasse o que tem que ser feito !

vc tirou todos os códigos que abrem e commitam transações?

So tenho commit no GenericDAO

então tira! o VRaptor já vai fazer isso pra vc

Funcionou !
E a aplicação ficou muito mais rápida !

Muito obrigado ao Lucas e o Rafael

David, pesquisa mais sobre hibernate pra descobrir pq sua app ficou bem mais rápida. Usar o hibernate sem entender o porque das coisas é bastante perigoso.

Sim. Isso aconteceu pq como não fechava as conexões com o banco ela acabava gerando processos gigantescos para o servidor.

esse não era o motivo de ficar lento… por causa disso uma hora o banco de dados ia parar de dar conexões e a aplicação ia parar.

É outra coisa.