Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

Solucionado
(ver solução)
21
respostas

imprimir nome do autor em livro.xhtml

coloquei livro.autor.nome mas está dando erro.

HTTP Status 500 – Internal Server Error
Type Exception Report

Message /livro.xhtml @93,51 value="#{livro.autor.nome}": Property [autor] not found on type [br.com.caelum.livraria.modelo.Livro]

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

javax.servlet.ServletException: /livro.xhtml @93,51 value="#{livro.autor.nome}": Property [autor] not found on type [br.com.caelum.livraria.modelo.Livro]
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:671)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause

javax.el.PropertyNotFoundException: /livro.xhtml @93,51 value="#{livro.autor.nome}": Property [autor] not found on type [br.com.caelum.livraria.modelo.Livro]
21 respostas

Olá Bruno,

A exceção diz que não existe a propriedade Autor no seu Livro.

verifique se sua classe contém um getter para Autor. Se isso não funcionar, coloque aqui o código da classe Autor para eu verificar o que está acontecendo.

package br.com.caelum.livraria.modelo;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Autor implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Integer id;
    private String nome;
    private String email;

    public String getEmail() {
        return email;
    }

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

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public Integer getId() {
        return id;
    }

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

}
package br.com.caelum.livraria.modelo;

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

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
public class Livro implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Integer id;

    private String titulo;
    private String isbn;
    private double preco;
    private Autor autor;

    //@ManyToMany
    //private Autor autor;

    @Temporal(TemporalType.DATE)
    private Calendar dataLancamento = Calendar.getInstance();

    @ManyToMany(fetch=FetchType.EAGER)
    private List<Autor> autores = new ArrayList<Autor>();

    public List<Autor> getAutores() {
        return autores;
    }

    public void adicionaAutor(Autor autor) {
        this.autores.add(autor);
    }

    public Livro() {
    }


    public Integer getId() {
        return id;
    }

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

    public String getTitulo() {
        return titulo;
    }

    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }

    public String getIsbn() {
        return isbn;
    }

    public Autor getAutor() {
        return autor;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public double getPreco() {
        return preco;
    }

    public void setPreco(double preco) {
        this.preco = preco;
    }

    public Calendar getDataLancamento() {
        return dataLancamento;
    }

    public void setDataLancamento(Calendar dataLancamento) {
        this.dataLancamento = dataLancamento;
    }

    public void removeAutor(Autor autor) {
        this.autores.remove(autor);
    }


}

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Novo Livro Livros

Sua linha que declara autor está comentada.

//@ManyToMany //private Autor autor;

tirei o comentario, fico assim

package br.com.caelum.livraria.modelo;

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

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
public class Livro implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Integer id;

    private String titulo;
    private String isbn;
    private double preco;

    //@ManyToMany
    private Autor autor;

    @Temporal(TemporalType.DATE)
    private Calendar dataLancamento = Calendar.getInstance();

    @ManyToMany(fetch=FetchType.EAGER)
    private List<Autor> autores = new ArrayList<Autor>();

    public List<Autor> getAutores() {
        return autores;
    }

    public void adicionaAutor(Autor autor) {
        this.autores.add(autor);
    }

    public Livro() {
    }


    public Integer getId() {
        return id;
    }

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

    public String getTitulo() {
        return titulo;
    }

    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }

    public String getIsbn() {
        return isbn;
    }

    public Autor getAutor() {
        return autor;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public double getPreco() {
        return preco;
    }

    public void setPreco(double preco) {
        this.preco = preco;
    }

    public Calendar getDataLancamento() {
        return dataLancamento;
    }

    public void setDataLancamento(Calendar dataLancamento) {
        this.dataLancamento = dataLancamento;
    }

    public void removeAutor(Autor autor) {
        this.autores.remove(autor);
    }
}

se eu descomentar //@ManyToMany nao compila.

ta acontencendo o seguinte quando grava o livro, o autor na tabela Livro nao tem informação

repara que o autor posso ter mais de um no mesmo livro, como faz pra mostrar no livro.xhtml. ?

Tudo bem, Bruno?

Como é um @ManyToMany, que indica que um livro pode ter vários autores, você vai precisar de uma lista de autores:

@ManyToMany
private List<Autor> autores = new ArrayList<>();

Tenta aí e diz no que deu? Abraço!

Lucas Félix, já está do jeito que mencionou.

package br.com.caelum.livraria.modelo;

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

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
public class Livro implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Integer id;

    private String titulo;
    private String isbn;
    private double preco;

    @ManyToOne
    private Autor autor;

    @Temporal(TemporalType.DATE)
    private Calendar dataLancamento = Calendar.getInstance();

    @ManyToMany(fetch=FetchType.EAGER)
    private List<Autor> autores = new ArrayList<Autor>();

    public List<Autor> getAutores() {
        return autores;
    }

    public void adicionaAutor(Autor autor) {
        this.autores.add(autor);
    }

    public Livro() {
    }


    public Integer getId() {
        return id;
    }

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

    public String getTitulo() {
        return titulo;
    }

    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }

    public String getIsbn() {
        return isbn;
    }

    public Autor getAutor() {
        return autor;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public double getPreco() {
        return preco;
    }

    public void setPreco(double preco) {
        this.preco = preco;
    }

    public Calendar getDataLancamento() {
        return dataLancamento;
    }

    public void setDataLancamento(Calendar dataLancamento) {
        this.dataLancamento = dataLancamento;
    }

    public void removeAutor(Autor autor) {
        this.autores.remove(autor);
    }
}

o problema é que não consigo imprimir o nome do autor . :(

Oi Bruno, como o Livro pode ter varios Autores e o Autor pode ter vários livros, retira a o @ManyToOne da sua classe Livro:

@ManyToOne
private Autor autor;

Posta aqui o código que você está utilizando para imprimir os nomes dos autores?

[]'s

eu tirei dexei somente private Autor autor;

subi o projeto na nuvem esse é o link, acredito que vai ser melhor, pra me ajudar :)

https://mega.nz/#!QNUWCCZT!q2qLBL4_W-yheuV21DnPB5YDu1jz4hXykK2xSQ7CIKY

Oi Bruno! Perdão pela demora.

O que é usado no curso para mostrar a lista de autores?

Realmente você não vai conseguir exibir o nome acessando ${livro.autor.nome}, pelo fato de que um livro pode ter vários autores.

Então teria que pegar a lista de autores do livro pra mostrar. Algo como:

${livro.autores}

E percorrer ela pra mostrar em algum componente do JSF.

A classe Livro vai ficar da seguinte forma:

https://github.com/alura-cursos/jsf/blob/master/src/br/com/caelum/livraria/modelo/Livro.java

[]'s

Lucas imagina obrigado pelo retorno, quase deu certo, esta mostrando essa informacao [br.com.caelum.livraria.modelo.Autor@519d5ca1], em vez do nome do autor

Opa Bruno!

Mas você fez ${livro.autores}?

O motivo dele mostrar dessa forma é por conta do toString(). Gera o toString() da sua classe Autor que aí você vai ver os valores dos atributos (talvez estejam nulos).

@Entity
public class Autor implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Integer id;
    private String nome;
    private String email;

    // getters e setters

    @Override
    public String toString() {
        return "Autor [id=" + id + ", nome=" + nome + ", email=" + email + "]";
    }
}

[bruno] como tiro "[]" ?

quando o autor é um só no livro, em vez de clicar do botao pra gravar autor, como faço pra gravar, a referencia do autor no livro, com só um botão, nao tendo que clicar em dois botão?

Oi Bruno.

Como você fez pra ele mostrar o texto "[bruno]"?

Para fazer isso você teria que assumir que o autor é o que está selecionado no Combobox e enviar esse valor.

html

                <p:column headerText="Autor" sortBy="#{livro.autores}"> 
                    <h:outputText value="${livro.autores}" />
                </p:column>

livroBean

    public List<Autor> getAutores() {
        return new DAO<Autor>(Autor.class).listaTodos();
    }

Autor coloquei o metodo toString() para não mostrar o endereco, mas o valor dele.

    @Override
    public String toString() {
        return  nome + "-" +email;
    }
solução!

Oi Bruno, eu tava olhando que você pode iterar sobre a lista no <p:column>. Se você passa o #{livro.autores} para o <h:outputText> ele vai pegar o toString() da lista:

 <p:column headerText="Autor" sortBy="#{livro.autores}"> 
    <h:outputText value="${livro.autores}" />
</p:column>

Deve ser algo próximo disso:

 <p:column value="#{livro.autores}" var="autor" headerText="Autor" sortBy="#{autor.nome}"> 
    <h:outputText value="#{autor.nome}" />
</p:column>