rowCount e paginação na mesma Criteria

rowCount e paginação na mesma Criteria

Boa tarde a todos,

Hoje me bati um bom tempo para fazer uma consulta paginada utilizando JPA com o Hibernate. Não foi pela dificuldade de montar a lógica da paginação, mas sim pelo simples motivo que eu precisava saber o total de registros que a minha consulta com N filtros iria retornar para que eu pudesse montar a paginação nas lógicas JSP do VRaptor 3.

A solução que eu tinha feito inicialmente foi fazer uma duplicação do meu método de consulta, logo eu tinha um método que retornava um List e outro que retorna um int, que nada mais era do que a mesma Criteria do outro método só que apenas adicionando um Projections.rowCount() e retornando um Criteria.uniqueResult() para obter o total de registros sem limitação.

Isso estava muito errado, pesquisei um pouco e achei a solução para isso, mantendo apenas um método de consulta apenas, logo o que foi necessário foi colocar o Projections.rowCount() daí chamar o método criteria.uniqueResult() e depois setar o criteria.setProjections( null ), desta forma eu poderia adicionar os Orders e os limits na consulta.

O problema que eu encontrei daí foi devido ao tipo do objeto retornado, que no caso era um Object que só fazia casting para Integer, isso devido ao fato de eu ter feito um casting do criteria.uniqueResult() para Integer, para isso eu precisei chamar o método da classe Criteria que corrige isso, no caso o criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);

Desta forma deixo abaixo o código do meu método de busca para que vocês tenham uma ideia da solução final.

Qualquer dúvida é só comentar, um forte abraço a todos.

Blog Java
  • Fabiano

    Nossa Carlos, era bem isso que eu procurava há tempos. Não consegui implementar porque ainda estou começando com java. To querendo usar aquele flexigrid com vraptor e esse teu esquema seria ideal. Vou tentar mais um pouco. Mas você já me fez crer que é possível e mostrou o norte. Valeu mesmo!

    • Boa tarde Fabiano,

      Que bom que foi útil para você, só queria lembrar que no caso de um row count para um SQL com N parâmetros, você sempre terá 2 queries sendo executadas, uma que faz um COUNT com base nas condições de filtro e a segunda que busca os seus dados solicitados. Na implementação do exemplo apenas re-utilizei a mesma Criteria para fazer isso, assim não necessito de dois métodos ‘countMinhaConsulta’ e ‘consultaMinhaConsulta’.

  • Fabiano

    Oi Carlos, tava pensando que vou ter que rever a implementaçao para as chamadas dos metodos que hoje uso @Get para obter uma lista. Porem agora vou precisar passar os parametros entao terei que chamar a uri via post, correto? Ja trabalhei com codeigniter no php, e lá eu tinha implementado legal o flexigrid, tambem só usava apenas uma query. aqui no java tava quebrando a cabeça pra nao ter que fazer as duas querys. ja usou flexigrid com java?
    Envio desde já meus sinceros agradecimentos à atenção.

    • Então, você pode usar get normalmente, mas se for uma aplicação full ajax você pode usar somente POST para reduzir a espionagem de parâmetros, mas da forma que for o VRaptor trabalha normalmente, no fim das contas você terá algo assim:

      //Injeção de parâmetros explícita.
      @Get (“/sistema/alguma-coisa/{categoria.id}/{produto.id}”)
      public void algumMetodo(Categoria categoria, Produto produto) {…}

      //Seletores oprimidos no post, são injetados diretamente.
      @Post (“/sistema/alguma-coisa/”)
      public void algumMetodo(Categoria categoria, Produto produto) {…}

      Já para o DAO, eu fiz uma ‘gambiarra’, na classe DAO eu tinha um atributo, ali na linha 19,20 e 21, assim eu poderia usar o método get desse count…

      public void logica(args…)
      {
      List consulta = dao.findHistoricoUsuario(parametros..);

      int count = dao.getLastQueryRowCount();

      //alguma lógica de construção de paginação…
      }

  • Fabiano

    Voce comanda Carlos. Hoje a noite vou continuar os testes, mas com sua ajuda já está mais claro as coisas. Obrigado mesmo. Assim que concluir eu posto o resultado aqui. E como ta foz do iguaçu? ja morei ai na vila C e no jd guarapuava. Adoro o calor dai. Forte abraço.

    • Opa, Bom dia Fabiano,

      Bom estudos aí cara, qualquer coisa ‘dá um grito aí’. Quanto a Foz do Iguaçu, estou me mudando no próximo sábado, estarei indo para São Paulo, vou trabalhar lá por um tempo.

      O calor daqui continua calor :), sempre quente e na ponte é pior as vezes.

  • Mattheus

    Valeu Carlos me ajudou muito.