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

Código não está funcionando - LazyDataModel

Prezados,

seguindo as instruções conforme segue o curso, me deparei com a classe LazyDataModel não compilando.

Tentei algumas alternativas (conforme sugerido aqui), porém não funcionou. Alguém pode me ajudar?

Segue o código da classe:

Código antes de refatorar DAO

public class LivroDataModel extends LazyDataModel<Livro> {

    private DAO<Livro> dao;

    public LivroDataModel() {
        this.dao = new DAO<Livro>(Livro.class); 
        super.setRowCount(dao.contaTodos());
    }

    @Override
    public List<Livro> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, Object> filters) {
        List<String> colunas = new ArrayList<String>();
        List<String> valores = new ArrayList<String>();

        for (Entry<String, Object> entry : filters.entrySet()) {
            colunas.add(entry.getKey());
            valores.add(entry.getValue().toString());
        } 

        return this.dao.listaTodosPaginada(first, pageSize, colunas, valores);
    }

}

Após refatorar a classe DAO, que agora recebe o EntityManger como parâmetro em seu construtor, tentei o seguinte (porém ainda não funcionando):

@Named
@ViewScoped
public class LivroDataModel extends LazyDataModel<Livro> {

    @Inject
    private LivroDAO livroDAO;

    @PostConstruct
    void init(){
        super.setRowCount(livroDAO.contaTodos());
    }

    @Override
    public List<Livro> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, Object> filters) {
        List<String> colunas = new ArrayList<String>();
        List<String> valores = new ArrayList<String>();

        for (Entry<String, Object> entry : filters.entrySet()) {
            colunas.add(entry.getKey());
            valores.add(entry.getValue().toString());
        } 

        return this.livroDAO.listaTodosPaginada(first, pageSize, colunas, valores);
    }

}

Porém o comportamento estranho que percebi é:

O método load é chamado antes de ocorrer a injeção e antes da chamada ao PostConstruct. Tentei utilizando um construtor também, porém não funcionou...

A única forma que consegui fazer funcionar foi sem utilizar o CDI:

public class LivroDataModel extends LazyDataModel<Livro> {

    private DAO<Livro> livroDAO;

    public LivroDataModel() {
        this.livroDAO = new DAO<Livro>(new JPAUtil().getEntityManager(), Livro.class);
        super.setRowCount(livroDAO.contaTodos());
    }

    @Override
    public List<Livro> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, Object> filters) {
        List<String> colunas = new ArrayList<String>();
        List<String> valores = new ArrayList<String>();

        for (Entry<String, Object> entry : filters.entrySet()) {
            colunas.add(entry.getKey());
            valores.add(entry.getValue().toString());
        } 

        return this.livroDAO.listaTodosPaginada(first, pageSize, colunas, valores);
    }

}

Há alguma forma de conseguir fazer funcionar utilizando o CDI? Esta classe aparentemente não foi exibida no vídeo (talvez por ter sido desafio do outro módulo).

4 respostas

Fala aí Jefferson, blz?

Manda suas classes DAO e LivroDAO por favor .

Seguem:

package br.com.caelum.livraria.dao;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

public class DAO<T> implements Serializable {

    private final Class<T> classe;
    private EntityManager em;

    public DAO(EntityManager entityManager, Class<T> classe) {
        this.em = entityManager;
        this.classe = classe;
    }

    public void adiciona(T t) {

        // abre transacao
        em.getTransaction().begin();

        // persiste o objeto
        em.persist(t);

        // commita a transacao
        em.getTransaction().commit();
    }

    public void remove(T t) {
        em.getTransaction().begin();

        em.remove(em.merge(t));

        em.getTransaction().commit();
    }

    public void atualiza(T t) {
        em.getTransaction().begin();

        em.merge(t);

        em.getTransaction().commit();
    }

    public List<T> listaTodos() {
        CriteriaQuery<T> query = em.getCriteriaBuilder().createQuery(classe);
        query.select(query.from(classe));

        List<T> lista = em.createQuery(query).getResultList();

        return lista;
    }

    public T buscaPorId(Integer id) {
        T instancia = em.find(classe, id);
        return instancia;
    }

    public int contaTodos() {
        long result = (Long) em.createQuery("select count(n) from " + classe.getSimpleName() + " n")
                .getSingleResult();

        return (int) result;
    }

    public List<T> listaTodosPaginada(int firstResult, int maxResults) {
        CriteriaQuery<T> query = em.getCriteriaBuilder().createQuery(classe);
        query.select(query.from(classe));

        List<T> lista = em.createQuery(query).setFirstResult(firstResult)
                .setMaxResults(maxResults).getResultList();

        return lista;
    }

    public List<T> listaTodosPaginada(int firstResult, int maxResults, List<String> colunas, List<String> valores) {
        CriteriaQuery<T> query = em.getCriteriaBuilder().createQuery(classe);
        Root<T> root = query.from(classe);
        if(valores != null && !valores.isEmpty() && colunas != null && !colunas.isEmpty() && colunas.size() == valores.size()) {
            List<Predicate> predicates = new ArrayList<Predicate>();
            for (int i = 0; i < colunas.size(); i++) {
                predicates.add(em.getCriteriaBuilder().like(root.<String>get(colunas.get(i)), valores.get(i) + "%"));
            }

            query = query.where(predicates.toArray(new Predicate[predicates.size()]));
        }

        List<T> lista = em.createQuery(query).setFirstResult(firstResult).setMaxResults(maxResults).getResultList();

        return lista;
    }
}
package br.com.caelum.livraria.dao;

import java.io.Serializable;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.persistence.EntityManager;

import br.com.caelum.livraria.modelo.Livro;

public class LivroDAO implements Serializable {

    private static final long serialVersionUID = -6662277994148943606L;

    private DAO<Livro> dao;

    public int contaTodos() {
        return dao.contaTodos();
    }

    public List<Livro> listaTodosPaginada(int firstResult, int maxResults, List<String> colunas, List<String> valores) {
        return dao.listaTodosPaginada(firstResult, maxResults, colunas, valores);
    }

    @Inject
    private EntityManager entityManager;

    @PostConstruct
    public void init() {
        this.dao = new DAO<Livro>(entityManager, Livro.class);
    }

    public void adiciona(Livro t) {
        dao.adiciona(t);
    }

    public void remove(Livro t) {
        dao.remove(t);
    }

    public void atualiza(Livro t) {
        dao.atualiza(t);
    }

    public List<Livro> listaTodos() {
        return dao.listaTodos();
    }

    public Livro buscaPorId(Integer id) {
        return dao.buscaPorId(id);
    }

}
solução!

Fala aí Jefferson,

Tente assim:

public class LivroDataModel extends LazyDataModel<Livro> {

    @Inject
    private LivroDAO livroDAO;

    @PostConstruct
    void init(){
        super.setRowCount(livroDAO.contaTodos());
    }

    @Override
    public List<Livro> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, Object> filters) {
        List<String> colunas = new ArrayList<String>();
        List<String> valores = new ArrayList<String>();

        for (Entry<String, Object> entry : filters.entrySet()) {
            colunas.add(entry.getKey());
            valores.add(entry.getValue().toString());
        } 

        return this.livroDAO.listaTodosPaginada(first, pageSize, colunas, valores);
    }

}

E Injete ele no seu bean:

@Inject
private LivroDataModel dataModel;

Muito obrigado Fernando. Agora funcionou!

Pelo visto o que tinha faltado era injetar o LivroDataModel no bean.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software