Gente,
quero fazer uma consulta usando HQL do Hibernate. Quero consultar um aluno por determinado curso e cep, sendo que eu posso passar como parâmetros da consulta o nome do curso ou o cep ou ambos. Montei meu método de consulta assim:
@Repository
public class CursoRepositoryJpaImpl implements CursoRepository {
@PersistenceContext
private EntityManager entityManager;
@Override
public Curso consultarAlunoPorNomeDoCursoEhCepAluno(String nomeCurso, String cepAluno) {
String consulta = "select curso from Curso as curso left join fetch curso.alunos as aluno join fetch aluno.endereco as endereco " +
"where curso.nome = coalesce (:nomeCurso, curso.nome) " +
"and endereco.cep = coalesce (:cepAluno, endereco.cep)";
Query query = entityManager.createQuery(consulta);
query.setParameter("nomeCurso", nomeCurso);
query.setParameter("cepAluno", cepAluno);
try {
return (Curso) query.getSingleResult();
} catch (NoResultException nre) {
throw new NoResultException("Curso não encontrado");
} catch (NonUniqueResultException nre) {
throw new NonUniqueResultException("Retornou mais de um elemento");
}
}
}
E funciona quando eu passo apenas o cep ou quando eu passo ambos, nome do curso e cep do Aluno. O problema é quando eu passo somente o nome do curso. A consulta não me retorna nada. O interessante é que nesta condição, se eu tirar esta linha "and endereco.cep = coalesce (:cepAluno, endereco.cep)", ou seja, não passar o parâmetro cep=null, a consulta traz o resultado. O SQL que é montado está correto. Não sei porque nesta condição não funciona. Alguém já passou por algo parecido e saberia me explicar o que está havendo? Obrigado!
// Entidades
@Entity
@Table(name="CURSO")
public class Curso {
@Id
@Column(name="SEQ_CURSO", nullable=false)
@GeneratedValue(generator="curso_generator", strategy=GenerationType.SEQUENCE)
@SequenceGenerator(name="curso_generator", sequenceName="SQ_curso",schema = "xxxxx", initialValue=1, allocationSize=1)
private Integer sequencial;
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="curso")
private List<Aluno> alunos;
@Column(name="NOME", nullable=false)
private String nome;
//gets and sets
}
@Entity
@Table(name="ALUNO")
public class Aluno {
@Id
@Column(name="SEQ_ALUNO", nullable=false)
@GeneratedValue(generator="aluno_generator", strategy=GenerationType.SEQUENCE)
@SequenceGenerator(name="aluno_generator", sequenceName="SQ_ALUNO",schema = "xxxxx", initialValue=1, allocationSize=1)
private Integer sequencial;
@JoinColumn(name="SEQ_CURSO", referencedColumnName="SEQ_CURSO")
@ManyToOne(optional = false, fetch=FetchType.LAZY)
private Curso curso;
@OneToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="aluno")
private Endereco endereco;
//gets and sets
}
@Entity
@Table(name="ENDERECO")
public class Endereco {
@Id
@Column(name="SEQ_ENDERECO", nullable=false)
@GeneratedValue(generator="endereco_generator", strategy=GenerationType.SEQUENCE)
@SequenceGenerator(name="endereco_generator", sequenceName="SQ_ENDERECO",schema = "xxxxx", initialValue=1, allocationSize=1)
private Integer sequencial;
@OneToOne(fetch=FetchType.LAZY, optional=true)
@JoinColumn(name="SEQ_ALUNO")
private Aluno aluno;
@Column(name="CEP")
private String cep;
//gets and sets
}
