Session no Hibernate, qual a melhor forma de uso?

Opa! :smiley:
Senhores, estou tendo muitos problemas com a famosa LazyInitializationException.

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.app.beans.Proposta.rebanhos, no session or session was closed
Pelo que vi, uma forma de contornar esse erro é sempre manter a Session aberta. OK. Funciona, mas qual a melhor forma de fazer isso?

Pensei no seguinte:
Assim que o usuário se logar, jogo o objeto Session na sessão http dele e sempre pego de lá.

Existe algum problema com isso? Corro o risco de alguém pegar o objeto Session errado?

Outra alternativa seria sempre chamar o método HibernateUtil.getSession() e nunca fechá-lo.
No caso dessa alternativa, posso ter problemas de memória? Ou o Hibernate mata a Session que ficou aberta e está sem uso?

Toda ajuda é bem vinda 8)

eu não vou te ajudar muito mas só pra dar uma luz…

num curso q fiz na caelum lembro do instrutor explicar uma classe que servia como filtro de servlets…

ou seja toda vez que sua app fizesse uma requição ela passaria por esse filtro…e lá nesse filtro vc criaria sua session…

lembro q para criar tinha que implementar alguma coisa…

desculpe a falta de informação mas não lembro muito bem

[quote=Giulliano]eu não vou te ajudar muito mas só pra dar uma luz…

num curso q fiz na caelum lembro do instrutor explicar uma classe que servia como filtro de servlets…

ou seja toda vez que sua app fizesse uma requição ela passaria por esse filtro…e lá nesse filtro vc criaria sua session…

lembro q para criar tinha que implementar alguma coisa…

desculpe a falta de informação mas não lembro muito bem[/quote]

Tenho 1 exemplo desse filtro aki no Blog:
http://javawora.blogspot.com/2007/06/tutorial-parte-1.html :smiley:

pesquise sobre OpenSessionInView.

Cara eu apanhei muito com isso já…
É o seguinte, veja o código abaixo :

Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();		

this.meuObjeto = (MeuObjeto) session.load(MeuObjeto.class, id);						
session.getTransaction().commit();
session.close();

depois da ultima linha você nao consegue mesmo “mexer” com o meuObjeto.
Para isso no mapeamento do MeuObjeto você tem que fazer

<hibernate-mapping>

	<class name="br.pacote.model.MeuObjeto" table="tbMeuObjeto" lazy="false">
....

com o “lazy=“false”” você pode “mexer” com o objeto depois q a sessao foi fechada…
Na realidade quando o “lazy=“true”” ele só “traz” a informação do banco para seu objeto quando você precisa. (Obs.: Lazy=preguiçoso, ou seja, só traz qdo realmente precisar). Como sua session estava fechada, ele nao conseguia mais ir lah no banco e falar : "me dá o objeto que estou precisando agora"
Você colocando “lazy=“false”” no momento q vc dá um load, ele fala pro banco "me dá o objeto q eu vou ficar com ele mesmo depois q cair a minha ligação com você"
Conseguiu entender?? Td ok?

Senhores, aparentemente o OpenSessionInView resolve meus problemas, vou implementar ele aqui :wink:

Cleriston, entendi o que você disse, mas não posso deixar como lazy=“false”. O sistema é muito grande, com muitos relacionamentos e com muitos acessos simultâneos, isso iria deixá-lo muito lento.

Assim que implementar o esquema do OpenSessionInView coloco aqui se ficou tudo certo :wink:

Obrigado pela ajuda.

Senhores, implementei tudo e aparentemente está tudo funcionando :smiley:
Mas estou com um problema… :frowning:

Tenho uma listagem de orcamentos, com um link em cada uma para exclusão, quando mando excluir ele executa o seguinte metodo:

public String delete(){ OrcamentoDAO dao = new OrcamentoDAO(); dao.delete(dao.findById(new Integer(this.getRequest().getParameter("id")))); return Constants.ACTION_CADASTRO_ORCAMENTO; }
Depois da execução ele cai na mesma página de listagem e o registro excluído não aparece mais na lista.
Antes de implementar o OpenSessionInView, funcionava perfeito, agora não funciona.
Entendo o porque. Ele faz isso porque ele monta a página ANTES de comitar a transação que excluiu o meu objeto. Sendo assim, quando executo o método que popula minha lista de orcamentos, o cara que excluí ainda está lá. :?

Alguma sugestão de como resolver esse problemas :?:

*Se eu voltar a página com um “back” e depois retornar na pagina de orcamentos a lista está correta, sem o orcamento excluído.

saudações,
nao conheço OpenSessionInView porem o seu primeiro problema poderia ter sido resolvido se voce buscasse o objeto fazendo join no relacionamento, ou fazendo o seguinte no mesmo método após o q.list() ou q.uniqueResult:

 result = (Objeto) q.uniqueResult();
 Hibernate.initialize(result.subObjeto());

assim ele nao daria erro de LazyInitializationException.
e a principio o seu método de remoção voltaria a funcionar…

espero ter ajudado