Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Criar DataTable com Lazy

Andei olhando em alguns lugares como fazer uma datable com lazy, para poder carregar apenas os dados da pagina em exibição e não sobrecarregar o servidor. Mas todas explicações achei muito confusas. Alguém poderia me ajudar?

7 respostas

Oi Diego,

Não sei se já viu o próprio link do primefaces. Acho que a parte mais importante que você deve ver é que em vez de passar uma lista para o dataTable, você precisa passar alguém que implemente a interface LazyCarDataModel. Abaixo segue um exemplo pensando que vc quer usar o seu DAO.

/**
 * Dummy implementation of LazyDataModel that uses a list to mimic a real datasource like a database.
 */
public class LazyCarDataModel extends LazyDataModel<Car> {

    private ProdutoDAO dao;
    private List<Produto> produtos = new ArrayList<>();

    public LazyCarDataModel(ProdutoDAO dao) {
    this.dao = dao;
    }

    @Override
    public Car getRowData(Long id) {
        for(Produto p : produtos) {
            if(car.getId().equals(id))
                return p;
        }

        return null;
    }

    @Override
    public Object getRowKey(Produto produto) {
        return produto.getId();
    }

    @Override
    public List<Produto> load(int inicio, int quantidade, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
    //implementação simples. Pegue do 10 ao 30(se a páginação for de 20)
       return dao.listaPaginada(inicio,quantidade);
    }
}

Mas como eu integraria com meu ManagerBean e com o datatable do xhtml ? poderia me exemplificar? Pq quando nao utilizo lazy, no manager eu crio uma lista e atraves de um metodo eu adiciono o retorno da busca do meu DAO. Por Exemplo.

lista

private List listaProdutos = new ArrayList();

public void buscarLista() {

EntityManager manager = this.getEntityManager(); ProdutoDao produtoDao = new ProdutoDao(manager); listaProdutos.addAll(produtoDao.buscarLista()));

}

e no xhtml eu só linko o dataTable com essa list.

Pensando na lista de produto crie uma classe como a que Alberto falou e utilize no Bean algo como:

class ProdutoBean
@Inject
private LazyCarDataModel produtosModel;

public LazyDataModel<Produto> getDataModel() {
    return produtosModel;
}

e no xhtml algo como:

<p:dataTable value="#{produtoBean.dataModel}"
var="produto" lazy="true">
solução!

Também existe um exercicio sobre o LazyDataModel no curso:

https://cursos.alura.com.br/course/jsf-primefaces/section/5/task/12

abs

Muito obrigado a todos pelo suporte! Nico, o exercício que você postou me ajudou muito e conseguir fazer funcionar. Mas estou com um problema, eu tentei adicionar mais filtros e começou a dar erro. Como consigo concatenar os filtros no método Dao? outra coisa que percebi, que o filtro sem ser lazy ao digitar, ele busca qualquer parte do texto que se encontra nos dados da coluna. No modo lazy conforme o exercício ele busca apenas as que estão com as iniciais iguais as que forem digitados no filtro. Como posso fazer o filtro buscar qualquer parte do texto?

Eu fiz o seguinte método no meu DAO, com base nas aulas de JPA existente no Alura e mais o exemplo que o Nico passou.

Mas esta apresentando o seguinte erro:

com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback visit GRAVE: java.lang.NullPointerException

Segue o método abaixo: ... public List buscarListaDemandasSolicitadas(int firstResult, int maxResults, String colunaNomeProjeto, String valorNomeProjeto, String colunaSolicitante, String valorSolicitante) { System.out.println("------------------ Buscar Lista Demandas Solicitadas BD Lazy ----------------------");

CriteriaBuilder criteriaBuilder = manager.getCriteriaBuilder(); CriteriaQuery query = criteriaBuilder.createQuery(SolicitarDemandaBean.class); Root root = query.from(SolicitarDemandaBean.class);

Path nomeProjetoPath = root.get(colunaNomeProjeto); Path solicitantePath = root.get(colunaSolicitante);

List predicates = new ArrayList();

if(!valorNomeProjeto.isEmpty()) { Predicate nomeProjetoIgual = criteriaBuilder.like(nomeProjetoPath, valorNomeProjeto); predicates.add(nomeProjetoIgual); }

if(!valorSolicitante.isEmpty()) { Predicate SolicitanteIgual = criteriaBuilder.like(solicitantePath, valorSolicitante); predicates.add(SolicitanteIgual); }

query.where((Predicate[]) predicates.toArray(new Predicate[0])); List listaDemandas = manager.createQuery(query).setFirstResult(firstResult).setMaxResults(maxResults).getResultList(); return listaDemandas;

Alguém poderia me dizer o porque esta causando esse erro?

Grato!

Boa tarde,

Obrigado pela ajuda de todos, consegui fazer funcionar. O problema estava na minha verificação do if, ele não verifica por empty e sim como null.

So que eu gostaria de fazer um filtro like em um campo int, eu achei o método ge do criteria que seria apartir do numero digitado para os números mais altos do digitado. Mas ele não faz que nem o like. Se eu utilizar esse filtro sem lazy o próprio componente faz o like em um campo int perfeitamente, mas com o lazy não.

Se alguém poder ajudar ou tiver uma sugestão eu agradeceria muito!.

Grato!