Top Posts

Série Spring: Spring AOP com annotations

Continue lendo

Open Session View – Hibernate Solução

Posted by camilolopes | Posted in Hibernate | Posted on 14-07-2010

17

solutionproblem

olá Pessoal,

No post de hoje vou falar de um problema que todos que estão trabalhando com Hibernate não está livre de se deparar com ele. É o velho LazyInitializationException que acontece e deixa o pobre do desenvolvedor stressado.

Neste post pretendo ser menos teórico e mais prático, pois tem muita coisa na net explicando o porque temos o LazyInitializationException, porém poucos explicaram de forma prática a solução. O mais próximo foi este site. Que se você reparar direito tem um pequeno erro no mapeamento do filtro.

Então aqui vou mostrar como resolver o problema, pois também fui afetado com este problema e levei umas quase 3 horas para resolver. E agora vejo que era algo simples, mas eu precisava entender o por que?! de cada exceção que vinha recebendo. Para este este post usei o post que está no Jboss Community, porém fiz algumas adaptações.

Lets go…

Vou usar a técnica de reutilização da informação então o Paulo da Caelum já fez uma abordagem excelente do porque desse problema , veja.

Desenvolvendo

Se você não quer desenvolver os codes a seguir, então mude o relacionamento para EAGER ao invés de usar o LAZY. Os codes a seguir é útil para quem necessita de ser LAZY o relacionamento.

  1. crie um novo package no seu projeto o meu chamei de : br.com.filtro

O pessoal do Jboss Community não colocou quais classes deveriamos importar, um programador inexperiente pode se atrapalhar e importar classes inapropriadas. Em função disso coloquei abaixo o código completo.

  1. Crie a classe HibernateSessionRequestFilter conforme abaixo: (fique atento ao meu comentário na classe)

  2. Agora veja como está meu DAO:

Não precisei alterar nada da configuração padrão do hibernate.

  1. Abra seu arquivo hibernate.cfg.xml e adicione a linha abaixo:

    < property name=”hibernate.current_session_context_class”>thread  < /property>

  2. Salve e execute sua aplicação, veja se os println do Filter serão impressos (claro, os que estão nos catches nem devem aparecer). Em caso positivo está tudo ok.

  3. Agora teste várias vezes sua app e veja se verá o problema com LazyInitializationException. Aqui ele sumiu de vez, graças à deus.

A única coisa que mudei na classe HibernateSessionRequestFilter, foi informar meu SessionFactory e o resto o Filter fez o trabalho dele.

Bom vou ficando por aqui, espero que tenham gostado do post. Não posso deixar de agradecer ao autor Edson Gonçalves que contribuiu bastante para este post, desde a indicação do link, como as explanações pelo mesmo que foi contribuindo  até encontrar a solução, o colega Rafael Viana (GUJ) já tinha passado por um problema parecido e compartilhou sua experiência opinando como poderia ser resolvido.

Fica ai agora a versão em português do problema. Abracos, see you next post.

Related Posts with Thumbnails

Comments (17)

William Morais :
Opa Camilo, cara, que dica show! me ajudou demais, vlw mesmo!
só uma observação, depois se puder corrige ai colocando a linha toda que deve ser inserida no arquivo “hibernate.cfg.xml” que é:
thread
penei um pouquinho pra descobrir em qual propriedade eu tinha que setar “thread”, mas é só um detalhe pra ajudar os próximos que verem o post!!
[]s
William Morais

opa! Willian,

Valeu por avisar, na verdade eu coloquei, porem esses plugins para deixar o code organiado no eclipse é o que mata, ele alterou o conteudo, aff, odeio esses plugins tem hora. Mas, atualizei o post ja.
valeu! 😀

eu estou levando uma surra com esse LazyInitializationException, inclui o filter sugerido , mas nao mantem aberto , somente se retiro os session.close() do dao.

Olá,
Nem sempre LazyInitializationException está relacionado somente a session. É preciso ver o stacktrace das exception e vendo o que ele diz. Realmente se vc remover o .close() vai ficar aberto do contrario não. Veja tb onde vc está colocando o seu close().
flw.

Olá, a minha duvida é agora como ficará um GenericDAO.

o meu está assim:
public void incluir(T t) throws Exception {
Session sessao = HibernateUtil.getSession();
sessao.beginTransaction();
sessao.save(t);
sessao.getTransaction().commit();
sessao.close();
}

Está correto? Devo fechar a sessão ali?

HibernateUtil no meu caso é o DAO do seu exemplo.

se vc não for mais precisar da sessão após o commit, vc vai e fecha ela. No meu exemplo, na classe que extends a DAO eu gosto de colocar a sessão no finally do try/catch, assim eu sei que ao chegar no finally, já fiz tudo que tinha que fazer na sessão e ela será fechada. No seu caso acima me parece certo.

ninguem dorme por aqui .. !!! é so java no corujão!

eu sofro de insônia hehe :).

haha, programadores da madrugada :)

Obrigado, Lopes! Me ajudou bastante. Seu blog é um dos melhores de java.

definitivamente não consegui utilizar o filter com o session.close(); dentro do dao generic
só dentro do filter

Olá,
tem como postar um GenericDAO usando as classes acima. Só para matar a dúvida? Tá difícil de usar.

Não me ajudou!!!
Continua dando erro.
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: Classe, no session or session was closed

olá João,
Então você fez algum ponto errado ou há algo de diferente do seu relacionamento. Mas, essa é uma solução mais comum na internet para resolução do problema, inclusive possuo sistemas antigos em produção usando essa solução.
flw.

Olá Sergio, obrigado por compartilhar, você pode posta a classe SessionFactory? obrigado

Olá pessoal, do jeito que está o código não commita isso que dizer que ele apenas consulta mas não salva é necessário modificar o método da classe DAO para:
public static Session getSession() {
return sessionFactory.getCurrentSession();
}

agora sim vai funcionar :)

Write a comment