public class LivroDataModel extends LazyDataModel<Livro> {
...
@Override
public List<Livro> load(int inicio, int quantidade, String campoOrdenacao, SortOrder sentidoOrdenacao,
Map<String, Object> filtros) {
return dao.listaTodosPaginada(inicio, quantidade, filtros);
}
}
public class DAO<T> {
...
public List<T> listaTodosPaginada(int firstResult, int maxResults, Map<String, Object> filtros) {
EntityManager em = new JPAUtil().getEntityManager();
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<T> query = criteriaBuilder.createQuery(classe);
Root<T> from = query.from(classe);
Predicate conjunction = criteriaBuilder.conjunction();
for (Entry<String, Object> filtro : filtros.entrySet()) {
conjunction = criteriaBuilder.and(conjunction, criteriaBuilder
.like(from.<String>get(filtro.getKey()).as(String.class), "%" + filtro.getValue() + "%"));
}
query = query.where(conjunction);
List<T> lista = em.createQuery(query).setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
em.close();
return lista;
}
}
É importante notar que tive que converter Expression.as(String.class)
para os casos como a "Data de Lançamento".
No entanto esta solução não respeita as formas de filtragem definidas no xhtml
pelo fato de que o filtro é realizado com a função CriteriaBuilder.like()
com o valor no formato "%" + filtro.getValue() + "%"
- análogo a filterMatchMode="contains"
. Alguma sugestão?