1
resposta

Problema com Order By utilizando Specification e CriteriaBuilder

Olá, pessoal!

Estou utilizando Specification e CriteriaBuilder para construir uma query no Java JPA.

Problema: A cláusula “order by” não esta funcionando !!

A query funciona ,mas não esta ordernada. Ela aparece correta quando utilizo o “spring.jpa.show-sql=true”

Alguem sabe o porquê deste mistério?


public class TesteSpecsPesquisa {

  public static Specification<Teste> ordenarPorDescricao() {
    return new Specification<Teste>() {
      private static final long serialVersionUID = 184948473733L;
      @Override
      public Predicate toPredicate(Root<Teste> root, CriteriaQuery<?> query,
          CriteriaBuilder criteriaBuilder) {
        query.orderBy(criteriaBuilder.asc(root.get(Teste_.descricao)));
        return query.getRestriction();
      }
    };
  }

  public static Specification<Teste> buscarDescricao(String descricao) {
    return new Specification<Teste>() {
      private static final long serialVersionUID = 184948473733L;
      @Override
      public Predicate toPredicate(Root<Teste> root, CriteriaQuery<?> query,
          CriteriaBuilder criteriaBuilder) {
        return criteriaBuilder.like(criteriaBuilder.lower(root.get(Teste_.descricao)),
            descricao.toLowerCase() + "%");
      }
    };
  }
}

public List<Teste> listar(ParametrosPesquisaTesteDto parametro) {
    Specification<Teste> spec = TesteSpecsPesquisa.ordenarPorDescricao();
    if (parametro.getDescricao() != null) {
      spec = spec.and(TesteSpecsPesquisa.buscarDescricao(parametro.getDescricao()));
    }
    List<Teste> resultado = this.TesteRepository.findAll(where(spec));
    return resultado;
}
1 resposta

Olá, Elieldo!

Ao analisar o seu código, percebi que você está utilizando a cláusula "order by" dentro do método "toPredicate" da Specification "ordenarPorDescricao". Isso pode estar causando o problema, pois a cláusula "order by" deve ser utilizada fora do método "toPredicate", diretamente na construção da query.

Sendo assim, sugiro que você modifique o seu código para que a cláusula "order by" seja utilizada fora do método "toPredicate", conforme o exemplo abaixo:

public List<Teste> listar(ParametrosPesquisaTesteDto parametro) {
    Specification<Teste> spec = TesteSpecsPesquisa.buscarDescricao(parametro.getDescricao());
    List<Teste> resultado = this.TesteRepository.findAll(spec, Sort.by(Sort.Direction.ASC, "descricao"));
    return resultado;
}

Dessa forma, a cláusula "order by" será adicionada diretamente na construção da query e deve funcionar corretamente.

Espero ter ajudado e bons estudos!