Bom, eu já vi que esse erro do Too Many Connections é bem comum e recorrente entre os utilizadores de Hibernate, e também achei vários tópicos resolvidos
sobre o mesmo assunto de que venho tratar, porém, nenhum me ajudou de fato à resolver o meu problema.
Esse erro ocorre após algum tempo de navegação no sistema, após várias chamadas ao servidor com pedidos de listagens de tabelas do banco de dados, com isso,
ele vai acumulando conexões e chega um ponto que isso tudo estoura. Eu sei também que esse erro pode ser “resolvido” com o simples aumento da variavel max_connections
do MySQL para cerca de 200 conexões (o padrão me parece ser 100). O problema é que isso só iria fazer demorar um pouquinho mais para a pool ficar cheia.
Consegui resolver o problema da pool acumulando conexões, ao simplesmente dar um close na session e na factory do Hibernate, mas isso me gerou outro problema: todos
os meus objetos que tem um fetch = FetchType.LAZY, falharam, afinal, não existia mais sessão alguma para que eles pudessem fazer o carregamento preguiçoso.
Ao alterar esses Objetos para fetch = FetchType.EAGER, obtive um outro erro, de “cannot fetch multiple bags simultaneously”. E com isso, fiquei em um beco sem saída.
A unica solução que consegui enxergar foi: antes de abrir uma nova conexão, eu deveria verificar se uma conexão já existe, e se existisse, eu pegaria essa, ao invés de
estabelecer uma nova. O problema é que não faço idéia de como ou onde fazer isso. Não sei se faço na minha classe HibernateUtil (segue classe abaixo) ou nas minhas classes DAO
(também abaixo).
Será que alguem pode me dar uma ajuda?
Exemplo de classe DAO:
package br.com.jm.dao;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import br.com.jm.beans.Setor;
import br.com.jm.beans.Usuario;
public class UsuarioDAO extends GenericDAO{
Session session = getSession();
@SuppressWarnings("unchecked")
public List<Usuario> all(){
Query query = session.createQuery("from Usuario");
List<Usuario> listaUsuarios = query.list();
return listaUsuarios;
}
public Usuario one(Usuario user){
Query query = session.createQuery("from Usuario usu where usu.idUsuario = ?");
query.setInteger(0, user.getIdUsuario());
Usuario usuario = (Usuario) query.uniqueResult();
return usuario;
}
public void update(Usuario user){
session.update(user);
session.getTransaction().commit();
}
public void delete(Usuario user){
session.delete(user);
session.getTransaction().commit();
}
public void insert(Usuario user){
session.save(user);
session.getTransaction().commit();
}
}
Classe extendida por todas as classes DAO:
package br.com.jm.dao;
import org.hibernate.Session;
import br.com.jm.config.HibernateUtil;
public abstract class GenericDAO {
public GenericDAO(){
}
protected static Session getSession(){
return HibernateUtil.getInstance().getSession();
}
}
E minha classe HibernateUtil:
package br.com.jm.config;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class HibernateUtil{
private static HibernateUtil me;
private SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
private HibernateUtil(){
try {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder().applySettings(
configuration.getProperties()).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public Session getSession() {
Session toReturn = sessionFactory.openSession();
toReturn.beginTransaction();
return toReturn;
}
public static HibernateUtil getInstance() {
if (me== null){
me = new HibernateUtil();
}
return me;
}
}