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

Dúvida no Ex. 3 da Aula 5 - Controlando o fluxo e resultado com Result

Oi gente!

Ao clicar o botao adiciona depois de preencher o formulario, lança a seguinte exception:

HTTP Status 500 - net.vidageek.mirror.exception.ReflectionProviderException: Could not invoke method adiciona
type Exception report
message net.vidageek.mirror.exception.ReflectionProviderException: Could not invoke method adiciona
description The server encountered an internal error that prevented it from fulfilling this request.

exception
javax.servlet.ServletException: net.vidageek.mirror.exception.ReflectionProviderException: Could not invoke method adiciona
    br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:120)

root cause
net.vidageek.mirror.exception.ReflectionProviderException: Could not invoke method adiciona
    net.vidageek.mirror.provider.java.PureJavaMethodReflectionProvider.invoke(PureJavaMethodReflectionProvider.java:45)
    net.vidageek.mirror.invoke.MethodHandlerByMethod.withArgs(MethodHandlerByMethod.java:54)
    br.com.caelum.vraptor.observer.ExecuteMethod.execute(ExecuteMethod.java:87)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
...
root cause
java.lang.NullPointerException
    br.com.caelum.vraptor.controller.ProdutoController.adiciona(ProdutoController.java:52)
    br.com.caelum.vraptor.controller.ProdutoController$Proxy$_$$_WeldClientProxy.adiciona(Unknown Source)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
...

Porém, apesar da exception lançada o produtodo é adicionado da lista! Não sei como resolver o problema!

Aqui está a classe ProdutoController:

@Controller
public class ProdutoController {

    private final Result result;

    public ProdutoController(Result result) {
        this.result = result;
    }

    public ProdutoController() {
        this(null);
    }

    @Get
    public void sobre() {
    }

    @Get
    public List<Produto> lista() {
        EntityManager em = JPAUtil.criaEntityManager();
        ProdutoDao dao = new ProdutoDao(em);
        return dao.lista();

    }

    @Get
    public void formulario() {
    }

    @Post
    public void adiciona(Produto produto) {
        EntityManager em = JPAUtil.criaEntityManager();
        ProdutoDao produtoDao = new ProdutoDao(em);
        em.getTransaction().begin();
        produtoDao.adiciona(produto);
        em.getTransaction().commit();
        result.forwardTo(this).lista();
    }

    @Remove
    public void remove(Produto produto) {

        EntityManager em = JPAUtil.criaEntityManager();
        ProdutoDao produtoDao = new ProdutoDao(em);
        em.getTransaction().begin();
        produtoDao.remove(produto);
        em.getTransaction().commit();
        result.forwardTo(this).lista();
    }

}
4 respostas

Oi Cremildo, tudo bem?

É provável que o problema seja porque não faltou a anotação pro CDI criar o Result, pois faltou a anotação @Inject no construtor.

O produto é adicionado porque a criação do EntityManager está sendo feita de forma manual.

Tenta mudar isso e vê se funciona:

@Controller
public class ProdutoController {

    private final Result result;

    @Inject // Indica que o Result deve ser criado
    public ProdutoController(Result result) {
        this.result = result;
    }

    public ProdutoController() {
        this(null);
    }

    @Get
    public void sobre() {
    }

    @Get
    public List<Produto> lista() {
        EntityManager em = JPAUtil.criaEntityManager();
        ProdutoDao dao = new ProdutoDao(em);
        return dao.lista();

    }

    @Get
    public void formulario() {
    }

    @Post
    public void adiciona(Produto produto) {
        EntityManager em = JPAUtil.criaEntityManager();
        ProdutoDao produtoDao = new ProdutoDao(em);
        em.getTransaction().begin();
        produtoDao.adiciona(produto);
        em.getTransaction().commit();
        result.forwardTo(this).lista();
    }

    @Remove
    public void remove(Produto produto) {

        EntityManager em = JPAUtil.criaEntityManager();
        ProdutoDao produtoDao = new ProdutoDao(em);
        em.getTransaction().begin();
        produtoDao.remove(produto);
        em.getTransaction().commit();
        result.forwardTo(this).lista();
    }

}

Abraço.

Oi Lucas!

É isso mesmo, faltava a anotação @inject, porém agora surgiu outro problema!

O método lista devolve uma lista vazia, sem produtos, após fazer a requisição. Aqui está o método lista:

@Get
    public void lista() {
        EntityManager em = JPAUtil.criaEntityManager();
        ProdutoDao dao = new ProdutoDao(em);
        List<Produto> lista = dao.lista();
        result.include(lista);
    }

Oi Cremildo.

Quando você utiliza o result.include() e passa apenas o objeto, o nome da variável disponível na jsp será o nome da classe com a primeira letra minúscula. No caso como você passou uma List, a variável disponível na jsp será list, que você vai recuperar via EL: ${list}.

Para manter o nome utilizado no curso você tem duas opções. Passar para o include() qual o nome da variável:

@Get
public void lista() {
    EntityManager em = JPAUtil.criaEntityManager();
    ProdutoDao dao = new ProdutoDao(em);
    List<Produto> lista = dao.lista();
    result.include("produtoList", lista);
}

Deixar o método retornando a List:

@Get
public List<Produto> lista() {
    EntityManager em = JPAUtil.criaEntityManager();
    ProdutoDao dao = new ProdutoDao(em);
    List<Produto> lista = dao.lista();
    return lista;
}

Testa e vê se é isso?

Abraço.

solução!

Oi Lucas!

a segunda alternativa funciona, a de passar a chave produtoList e valaor lista.

A primeira continua devolvendo uma lista vazia, talvez porque como há uma iteração para pegar a lista, a EL ${list} não pega os elementos da lista!

Em todo o caso, muito obrigado!