Possuo uma classe “Aluno” mapeada como “tb_aluno” e uma classe TurmaPeriodo mapeada como “tb_turma_periodo”.
Estas classes se relacionam da forma muitos para muitos (Many To Many) e a classe aluno contém uma coleção de TurmaPeriodo.
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name="tb_alunos_turmas_periodo", joinColumns={
@JoinColumn(name="aluno_id", nullable=false)
}, inverseJoinColumns={
@JoinColumn(name="turma_periodo_id", nullable=false)
})
private Set<TurmaPeriodo> turmasPeriodo;
O problema surge no momento em que eu desejo obter todos os alunos que possuem uma determinada TurmaPeriodo. Como a tabela de relacionamento é criada pelo próprio hibernate, não vejo uma forma de acessá-la utilizando código JPA. A forma que encontrei para fazer foi a seguinte:
CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Aluno> criteriaQuery = builder.createQuery(Aluno.class);
Root<Aluno> aluno = criteriaQuery.from(Aluno.class);
criteriaQuery.select(aluno);
Subquery<TurmaPeriodo> subquery = criteriaQuery.subquery(TurmaPeriodo.class);
Root<TurmaPeriodo> rootTurmaPeriodo = subquery.from(TurmaPeriodo.class);
subquery.select(rootTurmaPeriodo);
ParameterExpression<Integer> paramTurmaPeriodo = builder.parameter(Integer.class, "turmaPeriodo");
subquery.where(builder.equal(rootTurmaPeriodo.get("id"), paramTurmaPeriodo));
criteriaQuery.where(builder.exists(subquery));
TypedQuery<Aluno> query = getEntityManager().createQuery(criteriaQuery);
query.setParameter("turmaPeriodo", turmaPeriodo.getId());
List<Aluno> alunos = query.getResultList();
Infelizmente esta abordagem não deu certo, e não importa qual id de TurmaPeriodo eu passe, a consulta sempre me retorna o conjunto com todos os alunos cadastrados. O motivo disto eu já entendi, a cláusula EXISTS verifica que a turma existe e me retorna todos os alunos, pois não estou delimitando a igualdade no where interno. Porém não consegui encontrar uma solução para isso. Segue abaixo o código gerado pelo hibernate:
select
aluno0_.id as id1_7_,
aluno0_2_.email as email2_7_,
aluno0_2_.foto as foto3_7_,
aluno0_2_.nome as nome4_7_,
aluno0_1_.cpf as cpf1_8_,
aluno0_1_.data_expedicao as data_exp2_8_,
aluno0_1_.data_nascimento as data_nas3_8_,
aluno0_1_.orgao_expedidor as orgao_ex4_8_,
aluno0_1_.rg as rg5_8_,
aluno0_.data_matricula as data_mat1_0_
from
tb_aluno aluno0_
inner join
tb_pessoa_fisica aluno0_1_
on aluno0_.id=aluno0_1_.id
inner join
tb_pessoa aluno0_2_
on aluno0_.id=aluno0_2_.id
where
exists (
select
turmaperio1_.id
from
tb_turma_periodo turmaperio1_
where
turmaperio1_.id=?
)
Qualquer ajuda é bem vinda.