JPA, EJB e LazyLoading - Lazy maldito não funciona
18 respostas
Felagund
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.
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
marcusmage
Cara se sua aplicação é uma aplicação WEb vc pode utilizar o padrão OpenSessionInView.
Em: http://hibernate.org/43.html
[]
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.
To dando uma pesquisada aqui.
[]'s
felipeguerra
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.
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…
Felagund
Sim com HQL, ou melhor JPQL é JPA
felipeguerra
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?
rafaelk
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.
Felagund
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
felipeguerra
É, só olhando o código mesmo…
Felagund
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.
rafaelk
bom, algumas perguntas:
O mapeamento é bidirecional ?
A coleções estão sendo inicializadas em que momento ?
Você alterou o FechType nas coleções ?
Felagund
1- Sim é bidirecional
2 - Em nenhum momento, aparecem inicializadas apos o merge
3 - Sim, tudo LAZY.
[]'s
rafaelk
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.
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 !
Felagund
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).
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
rodrigosanders
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.
Felagund
Resolvemos esse problema colocando tudo como lazy e removendo os fetch join. Apos a busca utilizamos o Hibernate.initialize para carrega objetos lazy.