É válido lembrar que para que o JPA insira os registros corretamente no banco, o relacionamento deve estar explícito e por isso é recomendável utilizar um método (neste caso o método addCategoria) para efetuar este relacionamento.
Espero que tenha ajudado.
Boa sorte!
guigouz
Funcionou perfeito. Achei que fosse bem mais complexo que isso.
Sabe dizer se essas queries são otimizadas ?
Valeu
gui
henrique.lima
Olá guigous, esse é um tipo de relacionamento muito simples e o JPA por default carrega seus objetos em modo lazy. Isso quer dizer que toda vez que você carregar uma Categoria as suas subcategorias não serão carregadas (o que é muito bom). Quando você precisar das subcategorias o método getCategorias() será chamado e apenas nesta hora a query (where idPai = x) será executada. As subcategorias das categorias contidas na collection obtidas pelo método getCategorias() também não terão suas subcategorias carregadas que é exatamente como eu faria com jdbc puro.
Desta forma, acredito que não haja mais nada que se possa otimizar neste tipo de relacionamento.
Espero ter sido claro na explicação.
Bons estudos! =)
guigouz
Eu to tendo um problema com o LazyLoad... usando Glassfish e Hibernate. Tenho uma entidade que tem vários filhos (nem é hierárquico como o exemplo que você passou, são duas entidades diferentes)... Um TreeBean (stateless EJB) pega a Entidade com o código
publicList<Bem>todos(){
List<Bem>l=em.createQuery("SELECT b FROM Bem b").getResultList();System.out.println("FOUND "+l.size());returnl;}
Com isso eu monto uma lista de filhos pro cara abrir um e ver os detalhes. O erro que acontece quando vou acessar qualquer um dos filhos é
Exception in thread "AWT-EventQueue-0" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: br.com.prosoma.memoria.entidades.Bem.registrosConservacao, no session or session was closed
Ok... o getRegistrosConservacao(); tá rodando no app-client (local - swing) e a sessão tá no server... Tem alguma dica da lógica disso aí ? Fazer outra query no server talvez ? ou MeuBean.load(Bem) que carregue os campos (no server)
To tentando otimizar ao máximo o processo
valeu
henrique.lima
Olá guigous. Não sei se entendi muito bem o seu problema, pois de uma maneira geral a collection retornada pelo seu método todos() deveria ser carregada normalmente. Me parece que vc deve ter filhos em um relacionamento 1 - * onde vc precise utilizar algo do tipo:
Bemb=suaList.get(0);Listfilhos=b.getFilhos();// aqui pode deve ser onde a encrenca ocorre!
Os filhos não são carregados por causa do FetchType ser lazy e/ou seu ejb ser stateless. Uma maneira de resolver seria usar FetchType.EAGER ou então um stateful EJB. As duas soluções devem ser implementadas com cautela.
Se você puder detalhar melhor o seu problema, prometo me esforçar para tentar ajuda-lo.
Desculpe a demora para responder.
Abraço.
B
brunoja
henrique.lima:
Olá guigous, esse é um tipo de relacionamento muito simples e o JPA por default carrega seus objetos em modo lazy. Isso quer dizer que toda vez que você carregar uma Categoria as suas subcategorias não serão carregadas (o que é muito bom). Quando você precisar das subcategorias o método getCategorias() será chamado e apenas nesta hora a query (where idPai = x) será executada. As subcategorias das categorias contidas na collection obtidas pelo método getCategorias() também não terão suas subcategorias carregadas que é exatamente como eu faria com jdbc puro.
Desta forma, acredito que não haja mais nada que se possa otimizar neste tipo de relacionamento.
Espero ter sido claro na explicação.
Bons estudos! =)
Estou tendo um problema com o ManyToOne, ele ta carregando em modo eager, mesmo eu declarando: fetch = FetchType.LAZY!
O meu problema era dentro do container, eu fazia a query no server, e precisava acessar as listas no cliente. Como na sua solução, que só funciona pro toplink, resolvi de um jeito que só funciona no hibernate, com
Coisa c = em.find(Coisa.class, 2L);
Hibernate.initialize(c.getFilhos());
Ainda chego em algo melhor, mas por enquanto funciona