Problemas com o Session do Hibernate

16 respostas
java
U

Estou desenvolvendo um aplicativo para um escritório de advocacia, e o mesmo aplicativo é usado por 18 maquinas, ele fica no servidor e tem em cada estação um atalho deste aplicativo, quando é efetuada uma pesquisa ele abre 1 conexão, mas quando pesquiso novamente, ele vai abrindo outras, como faço pra ele usar a mesma conexão sempre?

16 Respostas

R

Mas porque você quer que ele abra 1 única conexão para todos os clientes?
Isso não se faz, ta certo como está ocorrendo, abrir uma conexão para cada interação com o banco. O que você não pode deixar ocorrer é que essas conexões abertas permaneçam abertas, senão uma hora vai ser lançada uma exceção de falta de memória.

U

Acho que vc não entendeu, eu quero que seja aberto uma sessão por cliente, mas a cada pesquisa dos clientes, por cliente se abre 3 sessões a mais no caso, inicializa o software 1 sessão, 18 clientes = 18 sessões, realiza 1 pesquisa, mais 3 sessões abertas por cliente, 3 sessões = 54 sessões. isso que eu queria arrumar e ainda não sei como.

R

Mas como assim abre 3 sessões por cliente por vez? Você viu isso em algum log? Se está acontecendo é errado, tem alguma coisa implementada mal na sua app. Mas dai vai precisar postar as classes para a gente dar uma olhada.

O Hibernate deve abrir uma sessão a cada vez que você acessa o banco, mas não significa que vai abrir uma única sessão a cada vez que o cliente abre a aplicação e que ele vai trabalhar com ela o tempo todo. Se você faz um consulta ele abre uma sessão e fecha, se faz outra consulta ele abre outra sessão e fecha, e assim por diante. Por isso ele tem uma SessionFactory para criar quantas sessões forem necessárias e não usar apenas 1 para todo o ciclo de vida da instancia da aplicação.

U

Vou dar uma revisada no meu codigo, se não conseguir posto as classes.

U

Cara parecia que tinha resolvido, mas agora ta dando sessao duplicada, um usuario entra outro trava, ta bem cabuloso.

R

Você está usando algum pool de conexões? Como o C3p0 ou DBCP…

U

1
30
1800
50

U

hibernate.c3p0.min_size>1
hibernate.c3p0.max_size>30
hibernate.c3p0.timeout">1800
hibernate.c3p0.max_statements>50

U

cara como proceder?

R

Deve ter alguma coisa errada no seu código que você não percebeu. Tem como postar as classes que você cria a conexão e também a que você usa para persistir?

U

public class HibernateUtil {
private static SessionFactory sessionFactory;

static    
{    
    try    
    {      
        Configuration configuration = new Configuration().configure();    
        sessionFactory = configuration.buildSessionFactory();    
    }    
    catch (HibernateException he)    
    {    
        System.err.println("Error creating Session: " + he);    
        throw new ExceptionInInitializerError(he);    
    }    
}    

public static SessionFactory getSessionFactory()    
{    
    return sessionFactory;    
}

}

e o DAO generico

public class GenericDao {

private Transaction transaction;
private final Class class1;
Session session;

public GenericDao(Class<T> class1) {
    this.class1 = class1;
    this.session = HibernateUtil.getSessionFactory().openSession();
}

public void save(T o){
    try{            
        this.session = HibernateUtil.getSessionFactory().getCurrentSession();
        this.transaction = session.beginTransaction();
        this.session.saveOrUpdate(o);
        this.transaction.commit();
        this.session.close();
    }
    catch(HibernateException he){
        System.out.println("Erro ao inserir.\n"+he.getMessage());
    }

}
public void delete(T o){
    try{
        this.session = HibernateUtil.getSessionFactory().getCurrentSession();
        this.transaction = this.session.beginTransaction();
        this.session.delete(o);
        this.transaction.commit();
        this.session.close();
    }
    catch(HibernateException he){
        System.out.println("Erro na exclusão.\n Erro: "+he.getMessage());
    }

}
public void update(T o){
    try{
        this.session = HibernateUtil.getSessionFactory().getCurrentSession();
        this.transaction = session.beginTransaction();
        this.session.update(o);
        this.transaction.commit();
        this.session.close();
    }
    catch(HibernateException he){
        System.out.println("Erro ao atualizar.\n"+he.getMessage());
    }

}   

public List<T> listaCliente(String classe){
    
    List<T> listaTodos = null;
    try{
        this.session = HibernateUtil.getSessionFactory().getCurrentSession();
        this.transaction = session.beginTransaction();
        listaTodos = this.session.createQuery("from "+classe).list();
        
    }
    catch(HibernateException he){
        System.out.println("");
    }   

    return listaTodos;
}

public List<T> listaClienteEsp(String classe,Integer codigoCliente){
    
    List<T> listaClienteEspecifico = null;
    try{
        this.session = HibernateUtil.getSessionFactory().getCurrentSession();
        this.transaction = session.beginTransaction();
        listaClienteEspecifico = this.session.createQuery("from "+classe+" WHERE codigo = "+codigoCliente).list();
    
    }
    catch(HibernateException he){
        System.out.println("Erro consulta.\n"+he.getMessage());
    }

    return listaClienteEspecifico;
}

public List<T> tabelaTramite(int codTramite){
    
    List<T> listaT = null;
    try{
        this.session = HibernateUtil.getSessionFactory().getCurrentSession();
        this.transaction = session.beginTransaction();
        listaT = this.session.createQuery("from AcsTramite where tramite ="+codTramite).list();
        this.session.close();
    
    }catch(HibernateException he){
        System.out.println("Erro consulta.\n"+he.getMessage());
    }

    return listaT;
}

}

U
<?xml version="1.0" encoding="UTF-8"?> org.hibernate.dialect.MySQLDialect com.mysql.jdbc.Driver jdbc:mysql://172.16.16.253:3306/acs
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.show_sql">true</property>

<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">4Dv0c4c14</property>

<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">30</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statements">50</property>

<mapping class="br.com.inside.models.AcsClientes"/>
<mapping class="br.com.inside.models.AcsTramite"/>
R

Observei que no método construtor da classe GenericDao você atribui um session a variável session, porém, nos métodos você atribui novamente. Remova a session do construtor e deixe apenas nos métodos.
Outra coisa, nos métodos de consultas você não precisa abrir uma transação, pode remover.
Utilize a classe HibernateUtil como um Singleton, para garantir apenas uma única instancia dessa classe e uma única SessionFactory.

public class HibernateUtil {
	
	private SessionFactory sessionFactory;
	
	private static HibernateUtil instance;
	
	private HibernateUtil() {
		 try {      
			Configuration configuration = new Configuration().configure(); 
			sessionFactory = configuration.buildSessionFactory(); 
		} catch (HibernateException he) {    
			System.err.println("Error creating Session: " + he);    
			throw new ExceptionInInitializerError(he);    
		} 
	}
	
	public static synchronized getInstance() {
		if (instance == null) {
			instance = new HibernateUtil();
		}
		return instance;
	}

	public SessionFactory getSessionFactory() {    
		return sessionFactory;    
	}
}

E para obter a session em GenericDao faça:

this.session = HibernateUtil.getInstance().getSessionFactory().openSession();

Se você usar getCurrentSession(), não deve abrir transações, por padrão este método abre as transações por conta. Se você quiser abrir a transação, use o método openSession().

I
this.session.close(); nunca dentro do try né
U

Obrigado, pela ajuda, mas como utilizo o singleton? no caso acima?

U

kkkkkk erro sem necessidade, obrigado, nem percebi.

Criado 26 de janeiro de 2016
Ultima resposta 24 de out. de 2019
Respostas 16
Participantes 3