7
respostas

jpql join fetch em 2 tabelas ou mais

Boa noite como fazer o join fetch em mais de 2 tabelas? seria algo assim?

@NamedQuery(name = "Aluno.lista", query = "Select a from Aluno a join fetch a.enderecos p join fetch p.pais ")

Quando faço assim ele me retorna o erro :(

7 respostas

É Alisson, não rola mesmo.. para isso vc funcionar vc precisaria que os atributos do tipo Set. Por conta da repeti;cão de elementos.

Então não é possivel fazer uma junçao cm mais de 1 tabela? Então nesse caso o melhor a fazer é o comportamento eager? É que eu modelei minha classe assim, e queria fazer um select juntando todas as minhas classes!

@Entity
@NamedQueries({
    @NamedQuery(name = "Aluno.lista", query = "Select a from Aluno a join fetch a.enderecos p join fetch p.pais")
})
public class Aluno implements Serializable{



    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long codigo;
    private String nome;
    private Integer idade;
    @Temporal(TemporalType.DATE)
    private Calendar dataNascimento = Calendar.getInstance();
    @OneToMany(mappedBy = "aluno", orphanRemoval = true)
    private List<Endereco> enderecos = new ArrayList<Endereco>();
    @OneToOne
    @JoinColumn(name = "pais_codigo", referencedColumnName = "codigo")
    private Pais pais = new Pais();
    @OneToOne
    @JoinColumn(name = "classe_codigo", referencedColumnName = "codigo")
    private Classe classe = new Classe();

    public Long getCodigo() {
        return codigo;
    }
    public void setCodigo(Long codigo) {
        this.codigo = codigo;
    }
    public String getNome() {
        return nome;
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
    public List<Endereco> getEnderecos() {
        return enderecos;
    }
    public void setEnderecos(List<Endereco> enderecos) {
        this.enderecos = enderecos;
    }
    public Calendar getDataNascimento() {
        return dataNascimento;
    }
    public void setDataNascimento(Calendar dataNascimento) {
        this.dataNascimento = dataNascimento;
    }
    public Integer getIdade() {
        return idade;
    }
    public void setIdade(Integer idade) {
        this.idade = idade;
    }
    public Pais getPais() {
        return pais;
    }
    public void setPais(Pais pais) {
        this.pais = pais;
    }
    public Classe getClasse() {
        return classe;
    }
    public void setClasse(Classe classe) {
        this.classe = classe;
    }



}

Alberto e se eu sobrescreever o metodo toString? sera que ira retornar a minha lista na minha tag table dentro da xhtml?

Fala aí Alisson.

Então não rola fazer múltiplos joins em vários List.

Pois como uma lista preserva a posição dos elementos, o hibernate (por default) só consegue armazenar essa posição de uma lista. Na segunda lista ele irá se perder.

O mesmo caso ocorre quando você tem duas listas em uma mesma classe ou uma lista em uma classe e cada objeto dessa lista também tem uma lista, e tentar fazer com que as duas listas sejam eager. Rola uma exception org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags

A solução que o Alberto sugeriu é valida, tente mudar suas listas para conjuntos Set. Com isso o hibernate não precisa se preocupar com a ordem.

Fernando tudo bem? pois então o meu erro ainda não é na minha lista, e sim no meu named query, como que faz a junção multiplas? Igual postei a classe aluno ali encima como seria o select de todas as junções?

Fernando tava usando o Set e vi que não é possivel converter um set para list. porque eu sempre uso o metodo getResultList que me retorna uma lista, e quando faço o CAST para o set fala que não é possivel! Qual metodo usaria para fazer me retornar um set?

Fala aí Alisson, uma forma que você tem para fazer isso é pegar o retorno do getResultList e passar no construtor para uma implementação de Set por exemplo o HashSet.