Olá guigous, é possível efetuar este tipo de relacionamento em JPA, abaixo segue um trecho de código:
@Id
@GeneratedValue
private Long id;
@ManyToOne
private Categoria categoriaPai;
@OneToMany(mappedBy = "categoriaPai")
private List<Categoria> categorias = new ArrayList<Categoria>();
// metodos setters e getters
public void addCategoria(Categoria categoria) {
categoria.setCategoriaPai(this);
categorias.add(categoria);
}
É 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.
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.
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
[code] public List todos() {
List<Bem> l = em.createQuery("SELECT b FROM Bem b").getResultList();
System.out.println("FOUND " + l.size());
return l;
}[/code]
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 é
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)
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:
Bem b = suaList.get(0);
List filhos = 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.
[quote=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! =)[/quote]
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