Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

JOIN FETCH - A classe que eu estou resgatando da base de dados tem um atributo que é uma classe que tem um atributo que é uma outra classe. Como resgatar tudo com um JOIN FETCH?

Então.. eu fiz um projetinho sobre o que foi dado nesse curso, mas não estou conseguindo realizar o join fetch.

Meu problema: A tabela AlunoDisciplina possui 2 colunas que fazem referencia a outras tabelas: "id_aluno" e "id_disciplina".

A tabela Disciplina possui uma coluna que faz referência a outra tabela: "id_professor".

Mesmo realizando o JOIN FETCH em disciplina, os dados da classe Professor não estão sendo resgatados.

String jpql = "SELECT ad FROM AlunoDisciplina ad JOIN FETCH ad.disciplina where ad.id = :id";

Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy [modelo.Professor#4] - no Session

(eu ainda queria realizar um outro JOIN FETCH dentro do mesmo SELECT para resgatar os dados da classe Aluno)

@Entity
@Table(name = "aluno")
public class Aluno {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @Embedded
    private DadosPessoais dadosPessoais = new DadosPessoais();

    @OneToMany(mappedBy = "aluno", fetch = FetchType.LAZY)
    private List<AlunoDisciplina> alunoDisciplina = new ArrayList<>();
    ...
}

@Entity
@Table(name = "aluno_disciplina")
public class AlunoDisciplina {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_disciplina")
    private Disciplina disciplina;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_aluno")
    private Aluno aluno;
    ...
}

@Entity
public class Disciplina {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String nome;
    @Column(name = "data_inicio")
    private LocalDate dataInicio;
    @Column(name = "data_fim")
    private LocalDate dataFim;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_professor")
    private Professor professor;

    @OneToMany(mappedBy = "disciplina", fetch = FetchType.LAZY)
    List<AlunoDisciplina> alunoDisciplina = new ArrayList<>();
    ...
}

@Entity
@Table(name = "professor")
public class Professor {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @Embedded
    private DadosPessoais dadosPessoais = new DadosPessoais();

    @OneToMany(mappedBy = "professor", fetch = FetchType.LAZY)
    private List<Disciplina> disciplinas;
    ...
}


    public AlunoDisciplina buscarAlunoDisciplinaComDisciplinaEProfessor(Integer id) {
        String jpql = "SELECT ad FROM AlunoDisciplina ad JOIN FETCH ad.disciplina where ad.id = :id";
        return this.entityManager.createQuery(jpql, AlunoDisciplina.class).setParameter("id", id).getSingleResult();
    }

Eu quero saber como eu faço um JOIN FETCH nesse tipo de situação .

Minha solução ("gambiarra")

public AlunoDisciplina buscarAlunoDisciplinaComAlunoEDisciplinaEProfessor(Integer id) {
    String jpql = "SELECT ad, ad.aluno, ad.disciplina, ad.disciplina.professor FROM AlunoDisciplina ad where ad.id = :id";
    Object[] retornoConsulta = this.entityManager.createQuery(jpql, Object[].class).setParameter("id", id).getSingleResult();

    AlunoDisciplina alunoDisciplina = (AlunoDisciplina) retornoConsulta[0];
    Aluno aluno = (Aluno) retornoConsulta[1];
    Disciplina disciplina = (Disciplina) retornoConsulta[2];
    Professor professor = (Professor) retornoConsulta[3];

    disciplina.setProfessor(professor);        
    alunoDisciplina.setAluno(aluno);
    alunoDisciplina.setDisciplina(disciplina);

    return alunoDisciplina;
}
2 respostas
solução!

Oi Matheus,

Voce pode realizar outros join fetch na mesma consulta:

SELECT ad FROM AlunoDisciplina ad JOIN FETCH ad.disciplina d JOIN FETCH ad.aluno a JOIN FETCH d.professor p where ad.id = :id

Deu certo. Muito obrigado!!