Opa!
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?
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
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
Senhores, implementei tudo e aparentemente está tudo funcionando
Mas estou com um problema…
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…