Estou com um problema na minha aplicação, especificamente em uma classe que contem duas coleções!
Tenho uma classe Pessoa, que possui uma coleção de dependentes e uma coleção de telefones.
Estou utilizando Hiberbate + JSF, e sempre que realizo a busca de uma determinada pessoa, a tela de “Nova Pessoa” é preenchida com os dados da busca. Na tela existem ainda duas tabelas que são preenchidas: uma com todos os dependentes daquela pessoa, e outra com todos os telefones da pessoa.
O problema é que: na minha classe Pessoa, tanto a coleção de Telefones, quanto de Dependentes estão como EAGER. Se coloco uma como EAGER e outra como LAZY, a que está como Lazy causa o erro: “failed to lazily initialize a collection of role…”. Caso coloco as duas como EAGER, o erro é “cannot simultaneously fetch multiple bags”, mas se deixo uma coleção comentada e coloco a outra como EAGER, funciona! Não posso ter duas coleções EAGER numa mesma classe???
Não consigo manter as duas coleções funcionando!
(Sei que não deveria utilizar EAGER por que a performance pode cair…)
Não estou encontrando solução!
Alguém pode me ajudar?
Obrigado!
É dificil explicar. Se você procurar no google, tem gente que explica.
LAZY a coleção não retorna se vc recuperar seu objeto. No Momento em que vc solicita alguma informação da coleção, ele tenta recuperar os dados do banco sozinho.
Então vc tem uma Exception pois não pode mais acessar o banco pois sua conexao já foi fechada.
Existem várias soluções para seu caso. Uma delas é o Open Session In View. Outra é fazer uma select que retorne sua coleção e assim seter o retorno no seu bean
rogelgarcia
Problemas do hibernate…
Voce pode tentar usar esse comando Hibernate.initialize(proxy); para carregar as colecoes…
O problema é que como vc tá usando JSF nao sei se vc vai ter acesso a essa pessoa… (a sessao tem que estar aberta pro initialize funcionar)
aconstantino
Cara, existem algumas formas de resolver isso.
Vc cria uma query que retorna apenas os dados que vc precisa. Ex hql: select new PessoaVO(p.id, p.nome) from PessoaVO p where p.id = :id
Em seguida, vc recupera a sua colecao de telefones e dependentes e seta a lista no braco. ex: select new TelefoneVO(tel.id, tel.numero) from TelefoneVO tel where tel.pessoa.id = :idPessoa em seguida faria algo assim: Query q = s.createQuery(...); List lista = q.list();pessoa.listaTelefone(lista);
Vc pode tentar mudar de list para Set, pois set aceita isso… vc pode até dar join fetch em duas propriedades que funciona…
SELECT p FROM Pessoa p INNER JOIN FETCH p.telefones INNER JOIN FETCH p.dependentes
Pq o hibernate iria fazer uma query só e resolver seu problema. E outra, só a lógica dessa página que iria chamar esta query.
Outros locais da sua aplicação não iam fazer um fetch nas suas listas.
aconstantino
leandronsp:
Nesse caso, será que não poderia também usar:
SELECT p FROM Pessoa p INNER JOIN FETCH p.telefones INNER JOIN FETCH p.dependentes
Pq o hibernate iria fazer uma query só e resolver seu problema. E outra, só a lógica dessa página que iria chamar esta query.
Outros locais da sua aplicação não iam fazer um fetch nas suas listas.