DevMedia - asp.net, Java, Delphi, SQL e web Design, tudo em um só lugar!
Bem vindo a DevMedia!
LOGIN:     SENHA:
 
 

Fórum DevMedia


Autor
Mensagem
ROGéRIO MARTINS
 

País: Brasil
Estado: GO
Cidade: Rio Verde
Mensagens: 24
 Postado em: 8/2/2011 11:24:08 AM

Salve galera!

Gostaria de saber de vcs qual a melhor opção de mapeamento em JPA

Collection, List ou Set

Realizando testes com JPA+Hibernate 3.5.0 Final descobri o seguinte:
Considerando as seguintes Entitys Class:
Pessoa (Pessoa possui uma lista de Email e Endereços)
Email
Endereco


Usando Set<>

1° Se eu uso Set<> com

#Código
fetch=FetchType.EAGER
nos mapeamentos funciona! Os seja, o metodo find do EntityManager traz os Sets preenchidos!
2° Se eu uso Set<> com
#Código
fetch=FetchType.LAZY
nos mapeamentos o método find do EntityManager retorna o seguinte erro:
#Código
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:

3. Quando utilizo Set mesmo sem fazer
#Código
fetch=FetchType.EAGER
consigo fazer o seguinte jp ql:
#Código
select p from Pessoa p
join fetch p.emailSet em
join fetch p.enderecoSet en
where p.pesId = 1

4. Outro problema que encontrei utilizando Set<> é o seguinte:
Set não aceita dados duplicados na lista como por exemplo uma lista de nomes:

Paulo
Paulo
Felipe

Se adiciono estes nomes em um Set os dados duplicados serão descartados ficando assim:

Paulo
Felipe

=====================================================================================
Usando List<>

1° Se eu uso List<> com

#Código
fetch=FetchType.EAGER
nos mapeamentos o método find do EntityManager retorna o seguinte erro:
#Código
org.hibernate.HibernateException: cannot simultaneously fetch multiple bags

2° Se eu uso List<> com
#Código
fetch=FetchType.LAZY
nos mapeamentos o método find do EntityManager retorna o seguinte erro:
#Código
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:

3. Quando utilizo List de nenhuma maneira consigo fazer o seguinte jp ql:
#Código
select p from Pessoa p
join fetch p.emailList em
join fetch p.enderecoList en
where p.pesId = 1

pois tenho o seguinte erro:
#Código
org.hibernate.HibernateException: cannot simultaneously fetch multiple bags

4. Utilizando List eu consigo fazer o seguinte jp ql e funciona!
#Código
select p from Pessoa p join fetch p.emailList

Só não consigo entender porque funciona com Set e não Funciona com List alguem puder me explicar? Devo utilizar Collection, List ou Set? Onde estou me perdendo?

Davi Gomes da Costa
 
 


País: Brasil
Estado: CE
Cidade: Fortaleza
Mensagens: 1770
 Postado em: 8/2/2011 12:18:37 PM
O problema do Lazy, é arquitetural,
é muito comum acontecer, talvez vc deva usar o Spring e sua entidade não tem nenhuma sessão aberta para vc simplesmente dar um get e ele abrir uma conexão do banco para fazer essa pesquisa sobe demanda.

Para sua lista de Set se for um objeto complexo (diferente de uma lista de String), vc deve sobrescrever o equals e o hashCode para um atributo q não se repete, como de repente vc pode usar o id. O nome pode se repetir.

Para os erros do List, eu teria que estar mais contextualizado, mas posso lhe adianta se nas classes envolvidas no mapeamente tiver muitos Eager, dá esse erro que vc citou. talvez sua classe só tenha um EAGER, mas se a classe que vc chamu tiver outros EAGER e ele e os EAGERs mais outros, assim o hibernate se perde.

Geralmente o que eu faço é deixar Eager quando realmente é útil e no serviço ao invez de recuperar via  objeto.getSuaDependencia() e fugir do lazyException é chamar via um serviço, por exemplo:
service.recuperaDependenciasObjeto(objeto)... e por aí vai.

Espero ter dado alguma luz

Att Davi

 
DYEGO SOUZA DO CARMO
 
 


País: Brasil
Estado: PR
Cidade: xxxxx
Mensagens: 1836
 Postado em: 11/2/2011 3:01:31 PM
Sugiro sempre List,

Lembrando que o Hibernate tem uma serie de "dores de barriga" com coleções complexas...

Principalmente aquelas do tipo LAZY dentro de updates (em.merge())...

Problemas arquiteturais e que a super "JBoss" se recusa a aceitar como BUG.

Mas a resposta do davi esta bem consistente.


 
ROGéRIO MARTINS
 

País: Brasil
Estado: GO
Cidade: Rio Verde
Mensagens: 24
 Postado em: 12/2/2011 4:31:21 PM
Tudo bem, qual seria a solução para o jp ql abaixo:

#Código
select p from Pessoa p
join fetch p.emailList em
join fetch p.enderecoList en
where p.pesId = 1

 
ROBSON PASSARELLA TEIXEIRA
 
 


País: Brasil
Estado: DF
Cidade: taguatinga
Mensagens: 518
 Postado em: 12/2/2011 5:12:26 PM
Olá Rogerio
 
   concordo com a resposta do Davi está excelente.
   com relação a sua ultima query postada o erro dela me parece que o seu provedor de persistencia não deixa fazer esses 2 join teste colocando virgula entre eles ou na anotação de 1 desses atributos eu colocaria fetch=FetchType.EAGER para trazer os e-mails ou endereços.

att
 robson

 
web-03
DevMedia  |  Anuncie  |  Fale conosco
Hospedagem web por Porta 80 Web Hosting
2013 - Todos os Direitos Reservados a web-03