[Resolvido] - Erro de sessão no hibernate

20 respostas
F

Ola pessoal, estou com o seguinte erro no hibernate.

Illegal attempt to associate a collection with two open sessions

Segundo minhas pesquisas nos foruns é que estou com duas sessões abertas.
Mesmo assim continuo com a dúvida de como resolver o problema.

Este é o meu DAO Genérico

public GenericDao(T t) {
		this.t = t;
	}
	public void gravar() {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tr = session.beginTransaction();
		session.save(t);
		tr.commit();
		session.close();
		return;
	}
	public void atualizar() {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tr = session.beginTransaction();
		session.update(t);
		tr.commit();
		session.close();
		return;
	}

O Service é:

public void addTriagem(Triagem t){ GenericDao<Triagem> dao = new GenericDao<Triagem>(t); dao.gravar(); } public void editTriagem(Triagem t){ GenericDao<Triagem> dao = new GenericDao<Triagem>(t); dao.atualizar(); }

Trexo de código onde adiciono é este

TriagemService triagemService = new TriagemService();
			triagemService.addTriagem(t);
			PacienteService pacienteService = new PacienteService();
			pacienteService.atualizaPaciente(paciente);

Desde já agradeço a ajuda de vocês.
Abraços!

20 Respostas

C

Você utiliza a mesma instanci de triagem para salvar e atualizar? ou cria uma nova para atualizar?

Também é interessante colocar o session.close() em um bloco finally só por precaução.

F

Todas as vezes que eu utilizo um serviço. Eu crio uma nova instancia.

C

Sugiro uns testes:
1- No seu método ao invés de utilizar openSession você poderia utilizar o getCurrentSession().

2 - Salvar a triagem, carrega-la da base, alterar uma propriedade e depois chamar o editTriagem.

F

Obrigado pela atenção calel

Então, tentei trocar os sessions por getCurrentSession.
da erro. Logo ao iniciar o sistema. Pois não existe nenhuma sessão corrente. (Acredito)

E quanto ao salvar a triagem. Eu tenho problemas na hora de salvar as alterações no paciente.

Quando debuguei o código ele mostra que o erro ocorre na segunda alteração!

:frowning: Vou testar novamente com outras formas de getCurrentSession();

Mais obrigado por enquanto!

C

Não tenho nenhum exemplo aqui, mas um pessoal falava de utilizar ThreadLocal para não ficar abrindo várias sessões também.

Esse getCurrentSession eu estava lendo que criava a session caso não existisse, podem ter me passado a informação incorreta… Mas caso ele retorne null você poderia fazer

session = getCurrentSession();
if( session == null)
   session = openSession();
F

calel, :frowning:
agora tenho outro erro. Tentei aplicar o getCurrentSession so na classe que realmente precisa.

Agora o erro é:

No CurrentSessionContext configured!

C

Tenta acrescentar essa linha no seu hibernate.cfg.xml

F

:frowning:
Então calel.
O Hibernate ta reclamando que:

Illegal attempt to associate a collection with two open sessions

Que eu abro duas sessões para uma unica operação!
Pelo certo aquele getCurrentSession();
era para funcionar.

Mais ñ to conseguindo fazer!

B

public void atualizar() { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction tr = session.beginTransaction(); session.update(t); tr.commit(); session.close(); return; << que p... é essa, o metodo não é void?? }

B

Mostra ai seu hibernate util…

F

Segue :D

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
	private static SessionFactory sessionFactory;
	static {
		Configuration cfg = new AnnotationConfiguration();
		cfg.configure("br/com/anglo/Clinica/util/hibernate.cfg.xml");
		sessionFactory = cfg.buildSessionFactory();
	}
	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
}

o return sem nada informa o fim do método. Mais posso tirar, ñ influencia em nada.

B
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

public class HibernateUtil {

	public static final SessionFactory sessionFactory;
	public static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();

	public HibernateUtil() {
	}

	static {
		try {
			sessionFactory = new AnnotationConfiguration().configure("br/com/anglo/Clinica/util/hibernate.cfg.xml").buildSessionFactory();
		} catch (Throwable ex) {        
			 System.err.println("-----------------------------Erro SessionFactory---------------------------------");
	         System.err.println("Initial SessionFactory creation failed." + ex);  
	         System.err.println("-----------------------------Fim SessionFactory---------------------------------");
	         throw new ExceptionInInitializerError(ex);  
	      }
	}

	public static Session getInstance() throws Exception {
		Session session = (Session) threadLocal.get();
		if (session == null) {
			session = sessionFactory.openSession();
			threadLocal.set(session);
		}
		return session;
	}
}

Usa esse... testa, vê o erro que vai dar no console...

B

Exemplo:

public class GenericDao {
	
	protected Session s;
	protected Transaction tr;
	protected Query q;

        public GenericDao(T t) {  
                this.t = t;  
        }

	public void salvar() throws Exception {
		s = HibernateUtil.getInstance();
		tr = null;
			try{
				tr = s.beginTransaction();
				s.save(t);
				tr.commit();
		} catch(Exception e){
			e.printStackTrace();
			tr.rollback();
		} finally{
			s.close();
		}
	}

Faz sua transação assim... não tem como dar merda, e se der você vai saber certinho onde foi...

F

mantem o mesmo erro! :?

F

Ola pessoal, :roll:
Conseguir resolver o problema.
Infelizmente era algo bobo que não consegui identificar no inicio.
Havia esquecido de fechar uma sessão de busca listagem de pacientes.
Por isso que ficou assim.

Desde já agradeço a atenção de todos.

J

FabioNoth, como resolveu o sem problema de duas sessões abertas?

Obrigado.

E

Nicocelli, leia o que está acima do seu post.

J

Falta de atenção da minha parte!
Não tinha visto que tinha duas páginas.

Obrigado.

D

calel:

session = getCurrentSession(); if( session == null) session = openSession();

[quote=calel]Tenta acrescentar essa linha no seu hibernate.cfg.xml

esses 2 trechos que o calel postou… ja resolveram meu problema o/* (tbm fechei a sessão do método de busca… no finally)

W

Eu estava tendo este erro, comecei a ler sobre o mesmo e analisar o sql que o hibernate estava gerando para a alteração.

Eu possuo uma classe Matriz que possui uma coleção de itens na classe ItemMatriz.

O meu mapeamento @OneToMany da classe matriz estava cascadetype.all por que realmente deve ser ! quando eu salvar a Matriz, ela deve salvar também os itens que eu setei.

O meu mapemante @ManyToOne da classe ItemMatriz também estava cascadetype.all (patiada minha) e ai estava dando o problema, pois quando eu alterava o item e tentava salvar, ele tentava cascatear para o pai e apresentava o problema de duas sessões abertas.

Eu alterei o cascade da classe filho e agora está gravando e alterando que é uma maravilha !

:slight_smile:

Criado 23 de novembro de 2011
Ultima resposta 29 de set. de 2012
Respostas 20
Participantes 7