[RESOLVIDO] Erro no JPA com Hibernate OneToMany  XML
Índice dos Fóruns » Persistência: Hibernate, JPA, JDBC e outros
Autor Mensagem
ctdaa
JavaGuru
[Avatar]

Membro desde: 12/08/2009 19:01:45
Mensagens: 222
Offline

Estou desenvolvendo uma aplicação de testes com JSF Facelet + JPA (hibernate) com mySQL e glassfish. O relacionamento entre as tabelas é o seguinte:
Categoria -> Produtos (OneToMany)
Produto -> Itens (OneToMany)
Endereço -> Itens (OneToMany)
Estou recebendo um erro quando o aplicativo vai carregar a página com detalhes de uma categoria selecionada, sendo que a categoria possui uma lista de produtos associados.
A mensagem é a seguinte:



A definição da bean categoria:


A definição da bean produto:


Alguém tem idéia do que pode estar acontecendo?








This message was edited 1 time. Last update was at 30/09/2009 15:28:19

[WWW]
ctdaa
JavaGuru
[Avatar]

Membro desde: 12/08/2009 19:01:45
Mensagens: 222
Offline

Encontrei uma solução parcial.
Coloquei um fetch=FetchType.EAGER em categoria e consegui mostrar os produtos relacionados:



Porém quando fiz o mesmo para produtos em relação a itens deu erro já no deploy:

  • java.lang.RuntimeException: javax.persistence.PersistenceException: [PersistenceUnit: facePetsPU] Unable to build EntityManagerFactory
    at com.sun.enterprise.web.WebModuleListener.loadPersistenceUnits(WebModuleListener.java:193)
    at com.sun.enterprise.web.WebModuleListener.lifecycleEvent(WebModuleListener.java:16
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:159)
    ...
    Caused by: javax.persistence.PersistenceException: [PersistenceUnit: facePetsPU] Unable to build EntityManagerFactory
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:677)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:132)
    at com.sun.enterprise.server.PersistenceUnitLoaderImpl.load(PersistenceUnitLoaderImpl.java:149)
    ...
    Caused by: org.hibernate.HibernateException: cannot simultaneously fetch multiple bags
    at org.hibernate.loader.BasicLoader.postInstantiate(BasicLoader.java:66)
    at org.hibernate.loader.entity.EntityLoader.<init>(EntityLoader.java:75)
    at org.hibernate.loader.entity.EntityLoader.<init>(EntityLoader.java:43)
    at org.hibernate.loader.entity.EntityLoader.<init>(EntityLoader.java:33)
    at org.hibernate.loader.entity.BatchingEntityLoader.createBatchingEntityLoader(BatchingEntityLoader.java:103)
    ...




  • [WWW]
    bronx
    JavaTeenager
    [Avatar]

    Membro desde: 24/08/2009 02:59:47
    Mensagens: 197
    Offline

    http://www.guj.com.br/posts/list/138649.java
    maior_abandonado
    JWizard
    [Avatar]

    Membro desde: 03/09/2007 11:30:08
    Mensagens: 2694
    Localização: sp
    Offline

    olha cara eu tenho um palpite...

    isso pelo erro, por que cabei nem olhando os seus beans ainda, fora o fato de que quando você muda pra EAGER funciona.

    o Hibernate fecha automaticamente a sessão quando vc da o commit, sendo assim, quando vc da o select de categorias ( e o commit em seguida) a conexão fecha, ai depois da o select dos produtos (comportamento do lazy) e a conexão ta fechada... por isso que funciona se você mudar pra EAGER (vai seleciona tudo usando um left outer join da vida, pegando as categorias e seus respectivos produtos).

    o que esta escrito no link que o bronx mando corrige, pelo que eu dei uma lida rapida enquanto escrevia essa resposta, resumidamente:

    crie um filtro, você vai abrir a sessão do hibernate no filtro, antes de da o select na pagina, coloca a sessão do hibernate na sessão do http (ou algum lugar que você possa acessar depois no controller), ai vc manda essa sessão pro dao fazer oq ue tiver que fazer, e o filtro depois da requisição deve fechar a sessão do hibernate (tirando essa responsabilidade do dao).

    aliais o jsf tem o PhaseListener (ja que vc ta usandoo jsf), da uma olhada nesse exemplo de como fazer para um login... cria uma classe

    http://www.rodrigolazoti.com.br/?p=56

    eu indicaria cria uma classe sua que implemente a PhaseListener, e outra pra seta e pegar a sessão do hibernate da httpSession... ou algo do tipo

    boa sorte

    espero ter ajudado...

    falando nisso, caso seu problema tenha sido resolvido, edite o seu primeiro post e coloque um [RESOLVIDO] no titulo do tópico.
    ctdaa
    JavaGuru
    [Avatar]

    Membro desde: 12/08/2009 19:01:45
    Mensagens: 222
    Offline

    Pessoal, obrigado pelas respostas... foram úteis para o aprendizado.
    Implementei o filtro conforme sugerido, o filtro foi acionado e até criou e recuperou as sessões armazenadas no httpSession de uma página de consulta para outra.
    Ótima lição.... mas o problema continuava.... foi quando percebi que no método de pesquisa das entidades havia um "close" no EntityManager (gerado automaticamente pelo netbeans).
    Bingo.... comentei o código e tudo funcionou perfeitamente.



    Existe aí então uma diferença nas implementações de persistência do TopLink (default sugerido pelo netbeans) e do Hibernate que estou usando agora?



    [WWW]
    ctdaa
    JavaGuru
    [Avatar]

    Membro desde: 12/08/2009 19:01:45
    Mensagens: 222
    Offline

    [WWW]
    Andre Brito
    JWizard

    Membro desde: 21/07/2007 17:44:31
    Mensagens: 2485
    Localização: Paraná
    Offline

    Opa. Estou com um problema parecido.
    Pelo que pude pesquisar e estudar e ler e coisa e tal, isso acontece porque o commit acontece e a sua view não foi renderizada ainda. Por isso, quando você comenta a linha do close funciona: ele não fecha a conexão e a view ainda pode renderizar. O problema é que você não fecha a conexão mesmo depois da view renderizada. Por isso do filtro que o maior_abandonado (preciso saber o nome deste usuário) falou (e é a 'resposta', ou uma das respostas corretas para o seu problema). Dependendo do que você usa (se usa Spring, EJB ou Serlvet ou coisa assim) fica bem fácil de configurar (é só colocar no web.xml, na verdade). Eu estou usando Blazeds com Java, Tomcat e Hibernate e não consegui achar uma solução, mas amanhã vou tentar mais um pouco e achar uma (se não tiver, vou ter que criar :p).

    Um link que recomendo você a ler é o Open Session in View, do site do Hibernate. Eu cheguei nele depois de ver que muita gente teve esse mesmo problema.

    Agora, se não fechar a conexão é algo aconselhável... Eu diria que não é.

    Sobre a diferença, acho que existe sim. Eu acredito que o Hibernate seja mais completo do que qualquer outra implementação da JPA...

    Abraço.

    This message was edited 3 times. Last update was at 24/09/2009 02:35:06


    Como organizar o GUJ.
    Meu Twitter.
    Meu blog.
    Future proofing means making code easy to change, not trying to anticipate every possible way your code might need to change.
    [WWW]
     
    Índice dos Fóruns » Persistência: Hibernate, JPA, JDBC e outros
    Ir para:   
    Powered by JForum 2.1.8 © JForum Team