JPA, EJB e LazyLoading - Lazy maldito não funciona

Galera,

vamos ver quem pode ajudar.
temos um problema aqui quando efetuamos o merge em uma entidade aqui, usando JPA e Hibernate. Apos fazer o merge tem duas collections que são pesadas e deveriam ser lazy, porem elas vem carregadas, e somente essas duas que vem carregadas. Ainda por cima aleatoriamente, não é sempre, nem toda a vez, que aparecem as duas preenchidas, as vezes é uma, as vezes nenhuma. E isso ta causando uma demora grande no cliente.

Alguém ai já passou por isso, sabe como resolver?

Ele ta invocando a lista do Lazy, pq em algum momento ela esta sendo acessada…

faça o seguinte…

ponha um break, no método que retorna a sua lista que é lay, dentro do seu bean … por exemplo, supondo que é uma lista de telefones no seu método getTelefones() …

ai rode o programa em debug… e veja os momentos em que a lsita é invocada… nessa hora q ele chama a lista lazy

Cara se sua aplicação é uma aplicação WEb vc pode utilizar o padrão OpenSessionInView.
Em:
http://hibernate.org/43.html

[]

O Client do EJB é Swing. Aplicação Desktop.

Ai que ta em nenhum momento é carregada a colection, nem acessada de modo algum, uma coisa que é feita e uma query simples, para buscar.

To dando uma pesquisada aqui.

[]'s

[quote=Felagund]O Client do EJB é Swing. Aplicação Desktop.

Ai que ta em nenhum momento é carregada a colection, nem acessada de modo algum, uma coisa que é feita e uma query simples, para buscar.
[/quote]
Com HQL?

Obs: pelo que vc ta falando, quase certeza que é algo simples e que passou desapercebido.

Open Session in View, macacos me mordam…cada besteira…

Sim com HQL, ou melhor JPQL é JPA

Ué, mas se as listas da sua entidade estão diferentes do banco, ao chamar o merge, a entidade retornada não devem vir com as atualizações?

Compreende onde quero chegar?

Seria interessante se você postasse o modelo (classes) onde o problema occore e o trecho de código onde estão as anotações do hibernate referente as coleções.

ai que ta vamos por partes

é uma entidade de usuario.
Quando ela faz login atualiza a data de ultimo login e faz um merge, nesse ponto as collections são lazy, não carregadas.
Apos feito o merge, as 2 collections são carregadas, não deveriam carregar.
Para contornar isso e feita outra busca para retornar o registro sem as collections, porém se for fazer isso toda a vez é muito trabalhoso, não vejo muita vantagem em usar assim.

Compreendo o que você quis dizer, mas o merge tem que retornar essas collections da base mesmo elas sendo Lazy? Acredito que a função do lazy é justamente impedir isso.

[]'s

É, só olhando o código mesmo…

Infelizmente não posso compartilhar o código, não no momento.
Porém esse problema ocorre somente nas entidades que tem relação com elas mesmo, que ocorre esse problema, as colections tão sempre carregadas, criando listas enormes, contendo outras listas enormes, e assim sucessivamente.

bom, algumas perguntas:

  • O mapeamento é bidirecional ?
  • A coleções estão sendo inicializadas em que momento ?
  • Você alterou o FechType nas coleções ?

1- Sim é bidirecional
2 - Em nenhum momento, aparecem inicializadas apos o merge
3 - Sim, tudo LAZY.

[]'s

desculpe-me, talvez me expressei mau, na última pergunta, estava me referindo a própria anotação FetchType, que define a estratégia para recuperar os dados de uma coleção no banco. Possíveis valores SELECT, SUBSELECT E JOIN.

No usuario, que possui a colection

@OneToMany(cascade = CascadeType.ALL, mappedBy = "idusu", fetch = FetchType.LAZY)

Na entidade da que o usuario possui uma collection

@JoinColumn(name = "IDUSU", referencedColumnName = "IDUSU", nullable = false)
    @ManyToOne(optional = false)

Cara, pensei que sua aplicação era web. Por isso sugeri o OpenSessioniNView!

VC pode alterar a configuração do fetch no seu mapeamento para a collection. Ou usar pode utilizar uma consulta com “left join fetch” (por eemplo).

Para o “felipeguerra” Vai Tomar no teu cú seu otário !

[quote=marcusmage]Cara, pensei que sua aplicação era web. Por isso sugeri o OpenSessioniNView!

VC pode alterar a configuração do fetch no seu mapeamento para a collection. Ou usar pode utilizar uma consulta com “left join fetch” (por eemplo).
[/quote]

Cara o problema não esta em não carregar a collection e acontecer um Lazy, e justamente ele carregar essa collection, coisa que não deveria acontecer, minha intenção é não carregar a collection.

[]'s

Felagund,
estou passando pelo mesmo problema que vc, minhas entidades estão como LAZY e estou carregando a entidade A e B com um JPQL JOIN FETCH(JPA), porém, a entidade C que está relacionada com B está sendo carregada em SQL’s dentro de loop(está como LAZY também). Já consultei outros fóruns e o problema ocorre em ambiente SE, para o provider do TopLink tem solução(http://www.oracle.com/technology/products/ias/toplink/JPA/essentials/toplink-jpa-extensions.html#LazyLoading), mas para Hibernate não achei nada ainda, você conseguiu resolver o problema?

Minhas configurações são:

  • spring 3
  • JPA 1.0 com Hibernate 3.3.2

Obs.: estou carregando as coleções através do JOIN FETCH para não usar o OpenSessionInViewFilter.

Abraço.

Resolvemos esse problema colocando tudo como lazy e removendo os fetch join. Apos a busca utilizamos o Hibernate.initialize para carrega objetos lazy.