funciona bem para a maioria dos casos, mas e possivel criar manualmente a consulta. Para simplificar as coisas nesta primeira versao, a consulta do count deve ser criada manualmente.Para os filtros o funcionamento vai ser semelhante ao do Seam, mas sem a restricao de permitir apenas uma expressao el por filtro.A classe abstrata tipada DataList estende a LazyDataModel fazendo todo o tratamento. Criei a classe como abstrata para que seja obrigatoria a implementacao dos metodos abaixo:protected Map<String, DataListFilter> getFiltros();protected abstract String getSqlList();protected abstract String getSqlCount();O principal metodo da classe LazyDataModel e o public List load(int first, int pageSize, String sortField, SortOrder sortOrder, Map filters). E necessario sobrescrever, pois ele sempre retorna UnsupportedOperationException("Lazy loading is not implemented.").O DataTable do Primefaces possui sistema de ordenacao e de filtros e eles sao repassados por esses parametros, juntamente com os dados referentes a paginacao:int first - Equivalente ao OFFSETint pageSize - Equivalente ao LIMITString sortField - Nome do campo usado na ordenacaoSortOrder sortOrder - Enum que indica se a ordenacao sera ASC ou DESCMap filters - Nessa map a key indica o nome do campo e o value o valor.Como o sistema de filtro do metodo load suporta apenas Strings, fiz um suporte para filtros com valores dinamicos baseados em 'el'.Para definir o filtro e preciso apenas sobrescrever o metodo getFiltros() como pode ser visto no exemplo abaixo. protected Map<String, DataListFilter> getFiltros() { filtros = new HashMap<String, DataListFilter>(); filtros.put("nome", new DataListFilter("AND o.nome like #{empty estadoDataList.nomeEstado ? null : estadoDataList.nomeEstado.concat('%')}")); filtros.put("sigla", new DataListFilter("AND o.sigla = #{estadoDataList.siglaEstado}")); return filtros; }A classe DataListFilter sera a responsavel pelas operacoes em cima do filtro. Basicamente ela precisa fazer o parse do filtro para encontrar todas as expressoes #{el} e transformar em um parametro da Query. Por exemplo para o filtro "AND o.sigla = #{estadoDataList.siglaEstado}" sera encontrada a el #{estadoDataList.siglaEstado} e a consulta EJB-QL sera AND o.sigla = :estadoDataList_siglaEstado.Outra coisa importante e avalizar todas as expressoes do filtro e caso todas retornem valor o metodo isPopulatedExpressions() retornara true. Isto e usado pela classe DataList para saber se o filtro deve ser adicionado na String da Query bem como no momento de aplicar os parametros.O regex que identifica e captura as expressoes e bastante simples e utiliza grupos para poder obter as informacoes de maneira mais facil: (\#\{(.*?)\})Para avaliar as expressoes criei o metodo abaixo, ele e bastante util em uma aplicacao JSF: private <C> C eval(String el, Class<C> classReturn) { FacesContext facesContext = FacesContext.getCurrentInstance(); Application application = facesContext.getApplication(); ExpressionFactory factory = application.getExpressionFactory(); ELContext elContext = facesContext.getELContext(); ValueExpression valueExpression = factory.createValueExpression(elContext, el, classReturn); return (C) valueExpression.getValue(elContext); }Na pratica a criacao do ManagedBean referente do DaraTable fica simples: package br.rodrigo.dao.list;import java.util.HashMap;import java.util.Map;import javax.enterprise.context.RequestScoped;import javax.faces.bean.ManagedBean;import javax.inject.Inject;import javax.persistence.EntityManager;import br.rodrigo.dao.DataList;import br.rodrigo.dao.DataListFilter;import br.rodrigo.model.Estado;@ManagedBean@RequestScopedpublic class EstadoDataList extends DataList<Estado> { private static final String SQL_LIST = "select o from Estado o"; private static final String SQL_COUNT = "select count(o) from Estado o"; private Map<String, DataListFilter> filtros; private String nomeEstado; private String siglaEstado; @Inject private EntityManager em; private static final long serialVersionUID = 1L; public String getNomeEstado() { return nomeEstado; } public void setNomeEstado(String nomeEstado) { this.nomeEstado = nomeEstado; } public