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

Uso do IS NULL na JPQL

Fala Rodrigo, beleza?

    public List<Produto> buscaPorListaDeParametros2(String nome, BigDecimal preco, LocalDate dataCadastro) {
        String jpql = "SELECT p FROM Produto p WHERE (:nome IS NULL OR p.nome=:nome) AND (:preco IS NULL OR p.preco=:preco) AND" +
                " (:dataCadastro IS NULL OR p.dataCadastro =: dataCadastro)";

        return entityManager.createQuery(jpql,Produto.class)
                .setParameter("nome", nome)
                .setParameter("preco", preco)
                .setParameter("dataCadastro", dataCadastro)
                .getResultList();
    }

Essa abordagem também seria válida?

4 respostas

Porquê você quer recuperar registros onde os valores são nulos?

Não é que eu esteja querendo recuperar valores nulos, eu estou querendo realizar uma consulta dinâmica sem utilizar a Criteria API, na qual eu passe todos, nenhum ou somente algum parâmetro e o método me retorne o produto.

Por exemplo:

        Produto produto = new Produto("Tênis", "Nike New", new BigDecimal("400"), categoria);
        List<Produto> produtos = produtoDao.buscaPorListaDeParametros("Tênis",null,null);
        produtos.forEach(produto -> System.out.println(produto));

Ele irá me retornar:

Produto(id=1, nome=Tênis, descricao=Nike New, preco=400.00, dataCadastro=2022-08-29, categoria=Categoria(id=1, nome=Sapatos))

No caso, se todos os argumentos passados no método sejam null, ele me retorna todos os dados do produto.

        List<Produto> produtos = produtoDao.buscaPorListaDeParametros(null,null,null);
        produtos.forEach(produto -> System.out.println(produto));

Retorno:

Produto(id=1, nome=Tênis, descricao=Nike New, preco=400.00, dataCadastro=2022-08-29, categoria=Categoria(id=1, nome=Sapatos))
Produto(id=2, nome=Sandália, descricao=DoPé New, preco=100.00, dataCadastro=2022-08-29, categoria=Categoria(id=1, nome=Sapatos))
Produto(id=3, nome=Chinelo, descricao=Havaianas New, preco=100.00, dataCadastro=2022-08-29, categoria=Categoria(id=1, nome=Sapatos))
Produto(id=4, nome=Tamanco, descricao=Zara New, preco=200.00, dataCadastro=2022-08-29, categoria=Categoria(id=1, nome=Sapatos))
Produto(id=5, nome=Society, descricao=Puma New, preco=300.00, dataCadastro=2022-08-29, categoria=Categoria(id=1, nome=Sapatos))

Acredito que tenha soluções melhores, com o uso de algum framework como o Spring Boot por exemplo.

Você pode tentar fazer algo nesse sentido também:

public List<Produto> buscaPorListaDeParametros2(String nome, BigDecimal preco, LocalDate dataCadastro) {
        String query = "SELECT p FROM Produto p ";
        String condicao = "WHERE ";

        if(nome != null) {
            query += condicao + "p.nome = :nome ";
            condicao = " AND ";
        }
        if(preco.toString().equals("") || preco.toString().equals("0")) {
            query += condicao + "p.preco = :preco ";
            condicao = " AND ";
        }
        if(dataCadastro != null) {
            query += condicao + "p.dataCadastro = :dataCadastro ";
        }

        var q = entityManager.createQuery(query, Produto.class);

        if(nome != null) {
            q.setParameter("nome", nome);
        }
        if(preco.toString().equals("") || preco.toString().equals("0")) {
            q.setParameter("preco", preco);
        }
        if(dataCadastro != null) {
            q.setParameter("dataCadastro", dataCadastro);
        }

        return q.getResultList();
}

Outra coisa, seu nome de método não está muito legal... Da uma olhada sobre clean code (código limpo) quando tiver um tempo sobrando também, talvez valha a pena.

OBS.: eu não testei esse código, quis mais te passar uma outra ideia de como poderia ser feito.

solução!

Oi Ayrton,

Sim, esse esquema de passar o (:campo IS NULL OR campo = :campo) é um "truque" do SQL para fazer consultas com parâmetros opcionais, resolvendo o problema de maneira bem simples :D

Bons estudos!