Ainda não tem acesso? Estude com a gente! Matricule-se
Ainda não tem acesso? Estude com a gente! Matricule-se

Solucionado (ver solução)

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>