Dúvida: fetch join e método find JPA

Olá galera estou usando as seguintes tecnologias: JSF 2.0, JPA/Hibernate, EJB, e estou com duas dúvidas:

1° O método find do EntityManager não retorna os Lists de um objeto consultado por ele populado? Ex:
Na Entity Class Pessoa eu tenho um List de emails. Mas quando consulto Pessoa pelo método find a lista de
emails não vem preenchida! Por que?

2° Usando jp ql quando faço a seguinte consulta:

select p from Pessoa p join fetch p.emailList where p.pesId = 1

Eu consigo trazer a Entity Class Pessoa e a lista de emails populada mas quando faço:

select p from Pessoa p join fetch p.emailList em join fetch p.enderecoList en where p.pesId = 1
Ou seja tento trazer mais de uma lista populada. Eu tenho o seguinte erro:

org.hibernate.HibernateException: cannot simultaneously fetch multiple bags

Esse erro de bags é porque você não está utilizando Set nas suas coleções.

Para carregar as listas junto com os objetos, defina essa associação como EAGER

No JPA 1 era assim pelo menos:

@OneToMany(fetch=FetchType.EAGER)

Utilizando Set e fetch=FetchType.EAGER funcionou! Vc poderia me explicar pq funciona com Set e não funciona com List?

Galera realizando testes 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 fetch=FetchType.EAGER nos mapeamentos funciona! Os seja, o metodo find do EntityManager traz os Sets preenchidos!
2° Se eu uso Set<> com fetch=FetchType.LAZY nos mapeamentos o método find do EntityManager retorna o seguinte erro:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:
  1. Quando utilizo Set mesmo sem fazer fetch=FetchType.EAGER consigo fazer o seguinte jp ql:

select p from Pessoa p join fetch p.emailSet em join fetch p.enderecoSet en where p.pesId = 1

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

1° Se eu uso List<> com fetch=FetchType.EAGER nos mapeamentos o método find do EntityManager retorna o seguinte erro:

org.hibernate.HibernateException: cannot simultaneously fetch multiple bags

2° Se eu uso List<> com fetch=FetchType.LAZY nos mapeamentos o método find do EntityManager retorna o seguinte erro:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role:
  1. Quando utilizo List de nenhuma maneira consigo fazer o seguinte jp ql:

select p from Pessoa p join fetch p.emailList em join fetch p.enderecoList en where p.pesId = 1
pois tenho o seguinte erro:

org.hibernate.HibernateException: cannot simultaneously fetch multiple bags
  1. Utilizando List eu consigo fazer o seguinte jp ql e funciona!
select p from Pessoa p join fetch p.emailList

Galera só não consigo entender porque utilizando Set funciona e com List não funciona! Alguém poderia explicar?

É realmente muito curioso. Eu estou enfrentando o mesmo problema, para mim não faz o menor sentido. Sei que o JPA trata de forma diferente quando você usa List ou Set como tipo da sua collection, mas realmente não me lembrava de algum tipo de problema nos fetchs!
Alguém ai sabe nos explicar?

Aparentemente a solução do erro é passar usar Set ao invés de List. :slight_smile: