LazyInitializationException

3 respostas
leonardobrancalhao

Boa tarde Galera,

Estou com problemas com o bendito LazyInitializationException, estava lendo no blog sobre o assunto: http://blog.caelum.com.br/enfrentando-a-lazyinitializationexception-no-hibernate/.

Estou usando o seguinte mapeamento:

//Classe PedidoCompra  
  
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pedido", targetEntity = ItemPedidoCompra.class)  
@Cascade(CascadeType.ALL)  
@IndexColumn(name = "indice")  
private List<ItemPedidoCompra> itens;

quando mudo o FetchType para EAGER ele funciona blz, porem quando para carregar uma grande quantidade de registro, totalmente inviável.

estou utilizando aplicação desktop, e nao estou conseguindo resolver esse problema, nao sei como fechar a sessao depois de carregar a lista.

//Classe PedidoCompraDao  
public List<PedidoCompra> listaEmAberto(Empresa emp) throws Exception{  
        Session s = HibernateUtil.getSession();  
        try {  
            Criteria c = s.createCriteria(PedidoCompra.class);  
            c.add(Restrictions.eq("cancelado", "N"));  
            c.add(Restrictions.eq("liberado", "N"));  
            c.add(Restrictions.eq("emp", emp));  
            return c.list();  
        } catch (Exception e) {  
            throw e;  
        } finally{  
            s.close();  
        }  
    }

Sei que a Exception acontece quando fecha a sessão mais como abri-la fora do Dao, ou enfim como fazer a implementacao mais adequada.

Antecipo meus agradecimentos.

3 Respostas

Paulo_Silveira

ola Leonardo

o problema é justo o seu s.close() dentro do finally. Em desktop, existem varias formas de resolver.

Voce pode fazer um Hibernate.initialize(pedido.getItens()) antes de fechar a sessao, dentro do select, ou ainda manter a sessao aberta, normalmente abrindo-a fora do seu dao (eu prefiro assim). Mas confesso que nao tenho experiencia com hibernate em ambiente desktop.

leonardobrancalhao

Alterei os mapemamentos para FetchType.Lazy, e alterei aguns metodos no DAO, quando necessito fazer o carregamento não preguiçoso, conforme a orientação do “Hibernate References”

public PedidoCompra buscaPorCodigo(Long cod, Empresa emp) throws Exception{
		Session s = HibernateUtil.getSession();
		try {
			Criteria c = s.createCriteria(PedidoCompra.class);
			c.add(Restrictions.eq("codigo", cod));
			c.add(Restrictions.eq("emp", emp));
			
			//essa parte
			c.setFetchMode("itens", FetchMode.JOIN);
			
			return (PedidoCompra)c.uniqueResult();
		} catch (Exception e) {
			throw e;
		} finally{
			s.close();
		}
	}

Mais ainda assim terei que mudar a arquitetura, para quando buscar uma grande quantidade de registro será necessário carregar a lista, pois não terei ela em memória.

Porém confesso que não sei se isso é viável, se o pessoal puder postar mais informações ficarei grato.

Paulo_Silveira

o fetchmode do criteria (ou join fetch do hql) realmente vao ajudar nisso: sobreescrevem a configuracao da anotacao para aquela query particular.

se voce pode ter dois metodos diferentes no dao para cada situacao, ou ainda criar um metodo separado que so carrega os itens!

Criado 19 de abril de 2011
Ultima resposta 19 de abr. de 2011
Respostas 3
Participantes 2