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

Não consigo visualizar um objeto na view

Boa tarde, to com um erro que parece ser simples, porém ainda não solucionei,

tenho uma classe Pedido, ItemPedido e Fornecedor, na classe pedido, tenho o id do fornecedor, e na classe itemPedido tenho o Id do pedido.

Ai tenho uma tela que visualiza o pedido e seus itens

tenho o seguinte dao

@SuppressWarnings("unchecked")
    public List <ItemPedido> listaItensPorPedido(Pedido pedido){

        String jpql = "select i from ItemPedido i where i.pedido = :pPedido";
        Query query = this.em.createQuery(jpql);
        query.setParameter("pPedido", pedido);
        return query.getResultList();
    }

o controller

@Get
    @Path("/pedido/visualizar{id}")
    public List<ItemPedido>visualizar(Pedido pedido){
        result.include("itemPedidoList", itemPedidoDao.lista());
        result.include("pedido", pedido);
        return itemPedidoDao.listaItensPorPedido(pedido);
    }

e o jsp

<h5><strong>Fornecedor: ${pedido.fornecedor.id } - Data Pedido: <tags:localDate date="${pedido.dataPedido }"/> - N° do Pedido: ${pedido.id }</strong></h5>

na view não consigo ver o pedido.fornecedor.id, não esta acessando o fornecedor! será que é problema no relacionamento?

Grato pela atenção!

6 respostas

No método do seu controller você está conseguindo receber o objeto pedido com um id? Se eu não me engano no vraptor para fazer o bind entre o parametro do método e o valor que esta vindo pela url, no seu caso vc teria que fazer um path assim:

@Path("/pedido/visualizar{pedido.id}")

Mas caso vc esteja conseguindo e seu pedido estiver vindo com um id então talvez seja sua query que não esteja retornando nada por você estar comparando dois objetos. Talvez assim funcione

String jpql = "select i from ItemPedido i where i.pedido.id = :pPedido";
Query query = this.em.createQuery(jpql);
        query.setParameter("pPedido", pedido.id);
        return query.getResultList();

Ah, pelo que eu percebi na sua query você esta tentando retornar um resultado (me corrija caso eu esteja errado), caso você realmente esteja tentando retornar apenas um resultado seria mais legal ao invés de

return query.getResultList();

Você usar algo como:

return query.getSingleResult();

Me avise caso tenha dado certo ou caso tenha dado errado. Valeu Rafael!

Olá, acho que faltou eu explicar que a consulta sql vem certa, o que não é ver apenas o Fornecedor da classe pedido, o listaItemPedido está ok.

JSP para vc entender melhor, é getResult mesmo

<h5><strong>Fornecedor: ${pedido.fornecedor.id } - Data Pedido: <tags:localDate date="${pedido.dataPedido }"/> - N° do Pedido: ${pedido.id }</strong></h5>

</div>
<div class="col-xs-6 col-md-4">

<img align="right" src="http://chart.apis.google.com/chart?cht=qr&chl=N do Pedido: ${pedido.id } - Data Pedido: ${pedido.dataPedido } &chs=120x120"
alt="Pedido - QR code"/>
</div>
</div>



<table class="table table-striped table-bordered table-hover">
            <thead>
                <tr>
                    <th>Nome Produto</th>
                    <th>Valor</th>
                    <th>Quantidade</th>
                    <th>Total</th>
                </tr>
              </thead>
              <tbody>

<c:set var="totalDePecas" value="" />
<c:set var="valorTotal" value="" />


<c:forEach items="${itemPedidoList}" var="itemPedido" varStatus="s">
                <c:set var="totalDePecas" value="${totalDePecas + itemPedido.quantidade}" />        

                <tr>

                    <td>${itemPedido.produto.nome}</td>    
                    <td><fmt:formatNumber type="currency" value="${itemPedido.produto.valor}"/></td>
                    <td>${itemPedido.quantidade}</td>    
                    <td><c:set var="total" value="${ itemPedido.quantidade * itemPedido.produto.valor}" /><fmt:formatNumber type="currency" value="${total }" /></td>    

                </tr>
                <c:set var="valorTotal" value="${valorTotal + total }" />
            </c:forEach>

            </tbody>
            </table>
<strong>Total de Peças pedidas: ${totalDePecas}</strong> - <strong>Valor Total do Pedido: <fmt:formatNumber type="currency" value=" ${valorTotal}"/></strong>

aqui que eu nao consigo pegar o fornecedor: esta comentado abaixo

@Get
    @Path("/pedido/visualizar{id}")
    public List<ItemPedido>visualizar(Pedido pedido){
        result.include("itemPedidoList", itemPedidoDao.lista());
        result.include("pedido", pedido); // aqui que nao pega o fornecedor, tipo: pedido.fornecedor.id que ja jsp ficaria ${pedido.fornecedor.id}
        return itemPedidoDao.listaItensPorPedido(pedido);
    }

Poderia por favor postar as classes Pedido, ItemPedido e Fornecedor?

Claro:

@Entity
public class Pedido {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    private Fornecedor fornecedor;

    @OneToMany(mappedBy = "pedido", targetEntity = ItemPedido.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<ItemPedido> itens;

    private LocalDate dataPedido = LocalDate.now();

    private String numeroPedido = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Fornecedor getFornecedor() {
        return fornecedor;
    }

    public void setFornecedor(Fornecedor fornecedor) {
        this.fornecedor = fornecedor;
    }

    public LocalDate getDataPedido() {
        return dataPedido;
    }

    public void setDataPedido(LocalDate dataPedido) {
        this.dataPedido = dataPedido;
    }

    public String getNumeroPedido() {
        return numeroPedido;
    }

    public void setNumeroPedido(String numeroPedido) {
        this.numeroPedido = numeroPedido;
    }

    public List<ItemPedido> getItens() {
        return itens;
    }

    public void setItens(List<ItemPedido> itens) {
        this.itens = itens;
    }

}
@Entity
public class ItemPedido {

    @Id
    @GeneratedValue
    private Long id;

    @OneToOne
    private Produto produto;

    @ManyToOne
    private Pedido pedido;

    @NotNull
    @Min(value = 0)
    private Integer quantidade;

    private BigDecimal produtoValor;

    private boolean statusDeEntrega;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Produto getProduto() {
        return produto;
    }

    public void setProduto(Produto produto) {
        this.produto = produto;
    }

    public Pedido getPedido() {
        return pedido;
    }

    public void setPedido(Pedido pedido) {
        this.pedido = pedido;
    }

    public Integer getQuantidade() {
        return quantidade;
    }

    public void setQuantidade(Integer quantidade) {
        this.quantidade = quantidade;
    }

    public BigDecimal getProdutoValor() {
        return produtoValor;
    }

    public void setProdutoValor(BigDecimal produtoValor) {
        this.produtoValor = produtoValor;
    }

    public boolean isStatusDeEntrega() {
        return statusDeEntrega;
    }

    public void setStatusDeEntrega(boolean statusDeEntrega) {
        this.statusDeEntrega = statusDeEntrega;
    }



}
@Entity
public class Fornecedor {

    @Id @GeneratedValue
    private Long id;

    private String razaoSocial;

    private Long cnpj;

    private String nomeFornecedor;

    private String telefone;

    private String whatsApp;

    private String email;

    @OneToMany(mappedBy = "fornecedor",targetEntity=Pedido.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<Pedido> pedidos;

    @OneToMany(mappedBy = "fornecedor",targetEntity=Nota.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<Nota> notas;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getRazaoSocial() {
        return razaoSocial;
    }

    public void setRazaoSocial(String razaoSocial) {
        this.razaoSocial = razaoSocial;
    }

    public Long getCnpj() {
        return cnpj;
    }

    public void setCnpj(Long cnpj) {
        this.cnpj = cnpj;
    }

    public String getNomeFornecedor() {
        return nomeFornecedor;
    }

    public void setNomeFornecedor(String nomeFornecedor) {
        this.nomeFornecedor = nomeFornecedor;
    }

    public String getTelefone() {
        return telefone;
    }

    public void setTelefone(String telefone) {
        this.telefone = telefone;
    }

    public String getWhatsApp() {
        return whatsApp;
    }

    public void setWhatsApp(String whatsApp) {
        this.whatsApp = whatsApp;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public List<Pedido> getPedidos() {
        return pedidos;
    }

    public void setPedidos(List<Pedido> pedidos) {
        this.pedidos = pedidos;
    }

    public List<Nota> getNotas() {
        return notas;
    }

    public void setNotas(List<Nota> notas) {
        this.notas = notas;
    }

}
solução!

Eai Rafael beleza? Eu não consegui entender muito bem o seu método do controller, então vou sugerir várias formas que talvez resolvam seu problema.

Primeiro, caso você queira que o objeto Pedido que chegou como parâmetro do seu método seja disponibilizado na view, vc pode apagar essa linha:

result.include("pedido", pedido);

e usar a anotação @IncludeParameters em cima do seu método, essa anotação disponibiliza todos os parâmetros que o método recebeu na view, ai por exemplo para acessar , no caso, o pedido, você só precisa chamar ${pedido.algumacoisa}

Segundo, caso você queira que a lista que retorna do método listaItensPorPedido() seja disponibilizada na view, então você tem que dar result include nela e no vraptor se usa métodos com retorno void, talvez seja por isso que você não está conseguindo acessar, lembre-se, sempre que você quiser acessar algo na sua view, você tem que disponibilizar o mesmo.

Tente mudar o método do seu controller para isso:

@Get
    @Path("/pedido/visualizar{id}")
    @IncludeParameters
    public void visualizar(Pedido pedido){
        result.include("itemPedidoList", itemPedidoDao.lista());
        result.include("pedido", pedido);
        result.include("algumNomeASuaEscolha",itemPedidoDao.listaItensPorPedido(pedido));
    }

Terceiro, como você está enviando só o id da view para o seu controller, o VRaptor está criando um objeto Pedido vazio apenas com o Id, então se você disponibilizar o mesmo objeto na view, ele estará vazio apenas com o ID, talvez seja por isso que você não esteja conseguindo acessar. O que você pode fazer é o seguinte, como você tem o ID, vc pode usar o método do dao que recupera um objeto dado algum id e pegar o pedido certo e jogar na view algo assim:

result.include("pedido", pedidaoDao.metodoQueDevolveUmObjetoDadoUmId(pedido.getId());

Acho que o terceiro jeito resolve seu problema. Qualquer dúvida, só mandar. Desculpa a demora e bons estudos!

Muito Obrigado @Mario Sergio, era uma solução bem simples, e vc além de responder deu uma aula de Vraptor.

ficou assim

@Get
    @Path("/pedido/visualizar{id}")
    @IncludeParameters
    public List<ItemPedido>visualizar(Pedido pedido){

        result.include("fornecedor" , dao.busca(pedido).getFornecedor().getRazaoSocial());

        return itemPedidoDao.listaItensPorPedido(pedido);
    }

e no jsp bastou chamar

${fornecedor}

Obrigado mesmo, cada vez fica mais nítido o funcionamento do VRaptor

Obrigado mesmo!!!