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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public List<HistoricoUsuario> findHistoricoUsuario(HistoricoConsulta historico, int limit,int page) throws HibernateException { Session session = (Session) this.getEntityManager().getDelegate(); Criteria criteria = session.createCriteria(HistoricoUsuario.class).createAlias("usuario", "u"); if(historico.getUsuario() != null && historico.getUsuario().getId() != null) { criteria.add(Restrictions.eq("u.id", historico.getUsuario().getId())); } if(historico.isComErro()) { criteria.add(Restrictions.isNotNull(&quot;exception&quot;)); } criteria.setProjection(Projections.rowCount()); Integer count = (Integer) criteria.uniqueResult(); // Flag publica para pegar o numero de registros do count(). this.setLastQueryRowCount (count.intValue()); criteria.setProjection (null); criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); criteria.setFirstResult ((page -1) * limit); criteria.setMaxResults (limit); criteria.addOrder(Order.desc("id")); return criteria.list(); } |
Qualquer dúvida é só comentar, um forte abraço a todos.