Ajuda urgente com org.hibernate.LazyInitializationException

12 respostas
fabioebner

Pessoal alguem me ajuda por favor… preciso enviar isso para ocliente amanha e nada.

tenho uma tabela tb_documento que tem varios filhos, tb_exigencia_documento, tb_parte e tb_imovel_documento

minha entity TbDocumento esta assim:

@OneToMany(mappedBy = "cdDocumento",cascade=CascadeType.REMOVE)
    private Collection<TbExigenciaDocumento> tbExigenciaDocumentoCollection;
    @OneToMany(mappedBy = "cdDocumento",cascade=CascadeType.REMOVE)
    private Collection<TbImovelDocumento> tbImovelDocumentoCollection;
    @OneToMany(mappedBy = "cdDocumento",cascade=CascadeType.REMOVE)
    private Collection<TbParte> tbParteCollection;

mas sempre retorna esse erro:

SEVERE: failed to lazily initialize a collection of role: br.com.dnasolution.entity.TbDocumento.tbDocumentoAndamentoCollection, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: br.com.dnasolution.entity.TbDocumento.tbDocumentoAndamentoCollection, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)

ja tentei de tudo tentei colocar um @CollectionId igual fala nessa pagina: http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/#entity-mapping-association-collections

ficou assim:

@OneToMany(cascade=CascadeType.REMOVE) @CollectionId(columns= @Column(name="COLLECTION_ID1"),type=@Type(type="long"),generator= "identity") private Collection<TbExigenciaDocumento> tbExigenciaDocumentoCollection; @OneToMany(cascade=CascadeType.REMOVE) @CollectionId(columns= @Column(name="COLLECTION_ID2"),type=@Type(type="long"),generator= "identity") private Collection<TbImovelDocumento> tbImovelDocumentoCollection; @OneToMany(cascade=CascadeType.REMOVE) @CollectionId(columns= @Column(name="COLLECTION_ID3"),type=@Type(type="long"),generator= "identity") private Collection<TbParte> tbParteCollection;

e nada.

ja tentei usar o

TbDocumento do = Entity.find(TbDocumento.class, 1); Hibernate.Initialize(do)
porem nesso momento eu perco minha referencia pois eu estou recuperando esse TbDocumento que esta dentro de uma outra entity TbProtocolo

logo ja tentei de tudo. e ate agora nada… alguem pode me ajudar??

valeu

12 Respostas

ignacio83

Esse seu sistema é Web?

Onde vc está fazendo o controle de transações/sessões do hibernate? Assim podemos matar o problema pela raiz

Porém a solução mais rápida, porém menos eficiente é colocar fetch=FetchType.EAGER no @OneToMany.
Pode retirar esse ColletionId…

tnaires

Complementando a resposta do colega ignacio83, pesquise sobre “open session in view”. No site do Hibernate tem um artigo sobre isso.

fabioebner

Entao amigos e sistema desktop… e outra ja tentei colocar o eager em tudo… e ele tbm da erro… fala q nao pode carregar mtos eager… alguma coisa assim

e eu faco controle de transacao sim… abro, salvo e commito, porem a conexao deixo sempre aberta…

ignacio83

Não conheço muito as arquiteturas desktop. Então não posso ajudar muito. Mas vou tentar explicar o erro…

Este erro ocorre porque o hibernate está tentando inicializar a Collection depois de vc ter fechado a sessão.
Tenta fazer isso:

TbDocumento do = Entity.find(TbDocumento.class, 1);   
Hibernate.initialize(do.getTbImovelDocumentoCollection());
//... Repita o processo para as três coleções.
fabioebner

Entao cara eu ja tentei… porem qual o meu problema… eu abro uma tela q eu carrego todos os protocolos,

cada protocolo pode ter 1 ou n documentos e cada documento pode ter 1 ou n parte, imovel, exigencia e andamento… qdo eu faco isso para um documento ele perde a referencia e depois se embanana todo … queria arrumar isso com a porcaria do eager, pq pra mim se trazer td de uma vez e melhor… entendeu

eu li q tem uns esquemas de BagInitialize qdo e collection ou set… la manda colocar uns esquemas de @IndexCollection ou @IndexColumn mas tbm nao funfa…

diego.urban

Estou enfrentando o mesmo problema numa aplicação web, mesmo implementando o OSIV.

Até pouco tempo atrás estive utilizanto o padrão de session-per-conversation, resolveu a questão da LazyException, porém desta forma os objetos não estavam atualizados de acordo com o banco, mesmo alterando o CacheMode para Ignore.

Para atualizá-los eu efetuava um refresh varrendo os objetos da consulta, más achei muita gambiarra isso que acabei desistindo da session-per-conversation.

O interceptador que utilizo é semelhante ao informado no link do artigo citado acima pelo naires, com a exceção de que eu não deixo a sessão aberta.
Penso não é aconselhável deixar a sessão aberta, ou é?

Não gostaria de resolver isto alterando o carregamento das coleções para eager.

Existe alguma forma elegante de resolver esse problema de LazyException?

fabioebner

E depois falam q o hibernate e melhor q o TopLink… nao tinha problemas com isso no toplink…

ignacio83

Já que está tralhando como uma mesma conexão… Não feche a session após o commit…

De tempos em tempos limpe o cache… Talvez funcione…

ignacio83

O Open Session in View Pattern resolve na maioria dos casos…

diego.urban

ignacio83:

Existe alguma forma elegante de resolver esse problema de LazyException?

O Open Session in View Pattern resolve na maioria dos casos…

Já estive utilizando OSIV semelhante ao informado no site do hibernate, porém ainda está ocorrendo LazyException.

fabioebner

mas eu nao fecho a session apos o comit… eu so dou begin trans e committrans… dai qdo eu saio do prgorama q eu dou um session.close()

entendeu

ziplove

Olha amigo

Tive um problema muito parecido e resolvi colocando nos meus mapeamentos OneToMany o fetch=FetchType.EAGER e depois o FechMode como no exemplo abaixo:

Ex.:

@OneToMany(mappedBy = task, fetch=FetchType.EAGER)

@Fetch(value = FetchMode.SUBSELECT)

private List activityTasks;

Espero ter ajudado.

Ab.

Criado 8 de maio de 2009
Ultima resposta 15 de out. de 2013
Respostas 12
Participantes 5