Concordo com o professor sobre o código da Criteria ser feio, também não gostei muito.
Mas também é possível eliminar os "if"s duplicados na JPQL. Testei o código abaixo e funcionou. Deve ser um pouco menos performático por ter um foreach, mas (na minha opinião) é um código mais organizado. O que acham?
public List<Produto> buscarPorParametros(String nome,
BigDecimal preco, LocalDate dataCadastro) {
String jpql = "SELECT p FROM Produto p WHERE 1=1 ";
HashMap<String,Object> parametros = new HashMap<String,Object>();
if (nome != null && !nome.trim().isEmpty()) {
jpql += " AND p.nome = :nome ";
parametros.put("nome", nome);
}
if (preco != null) {
jpql += " AND p.preco = :preco ";
parametros.put("preco", preco);
}
if (dataCadastro != null) {
jpql += " AND p.dataCadastro = :dataCadastro ";
parametros.put("dataCadastro", dataCadastro);
}
TypedQuery<Produto> query = em.createQuery(jpql, Produto.class);
parametros.forEach((key,value)->query.setParameter(key, value));
return query.getResultList();
}