Olá, Problema referente aos capitúlos 9 e 10 (CRUD com JSF)
Estou com um problema curioso ao tentar usar o Ajax para remover um autor da lista:
Quando preencho o formulário de autor, e clico em gravar, tudo ocorre OK, o novo autor é persistido. Mas se logo em seguida, tento remover esse mesmo autor que acabei de inserir, não acontece nada na página :/
Se dou refresh na página consigo remover ele normalmente, acredito que seja algum set no this.autor ou na lista de autores que não está ocorrendo de maneira correta
Essa é minha view:
<ui:define name="conteudo">
<h:form>
<h:messages id="messages" />
<fieldset>
<legend>Dados do Autor</legend>
<h:panelGrid columns="2">
<h:outputText value="Nome" for="nome" />
<h:inputText id="nome" value="#{autorBean.autor.nome}"
required="True" requiredMessage="Nome é Obrigatório">
<f:ajax event="blur" render="messages" />
</h:inputText>
</h:panelGrid>
<h:panelGrid columns="2">
<h:outputText value="Email" for="email" />
<h:inputText id="email" value="#{autorBean.autor.email}">
<f:passThroughAttribute name="type" value="email" />
</h:inputText>
</h:panelGrid>
<h:commandButton value="Gravar" action="#{autorBean.gravar}">
<f:ajax execute="@form" render="@form tabelaAutores" />
</h:commandButton>
<br /> <br />
<fieldset>
<legend>Lista de Autores</legend>
<h:dataTable id="tabelaAutores" value="#{autorBean.autores}"
var="autor">
<h:column>
<h:outputText value="#{autor.nome}" />
</h:column>
<h:column>
<h:commandButton id="removeAutor" value="X"
action="#{autorBean.remover(autor)}" immediate="true" />
</h:column>
<h:column>
<h:commandButton id="alteraAutor" value="Alterar"
action="#{autorBean.carregar(autor)}" />
</h:column>
</h:dataTable>
</fieldset>
</fieldset>
</h:form>
</ui:define>
Esse é meu MBean:
package br.com.alura.livraria.bean;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.persistence.EntityManager;
import br.com.alura.livraria.dao.AutorDAO;
import br.com.alura.livraria.model.Autor;
import br.com.alura.livraria.util.JpaUtil;
@ManagedBean
@ViewScoped
public class AutorBean {
private EntityManager em = new JpaUtil().getEntityManager();
private AutorDAO autorDAO = new AutorDAO(em);
private Autor autor = new Autor();
private List<Autor> autores;
public Autor getAutor() {
return autor;
}
public void setAutor(Autor autor) {
this.autor = autor;
}
public List<Autor> getAutores() {
this.autores = autorDAO.obterTodosAutores();
return this.autores;
}
public void setAutores(List<Autor> autores) {
this.autores = autores;
}
public void gravar() {
if(this.autor.getId() == null){
autorDAO.persist(autor);
System.out.println("Gravou o Autor: " + autor.getNome());
}else{
autorDAO.merge(autor);
System.out.println("Alterou o Autor: " + autor.getNome());
}
clear();
//return "livro?faces-redirect=true";
}
public void remover(Autor autor){
System.out.println("Removendo o autor: " + autor.getNome());
autorDAO.remove(autor);
System.out.println("Autor removido com sucesso.");
}
public void carregar(Autor autor){
this.autor = autor;
}
public void carregarPorId(){
Integer id = this.autor.getId();
this.autor = autorDAO.obterAutorPorId(id);
if (this.autor == null){
this.autor = new Autor();
}
}
public void clear(){
autor = new Autor();
}
}
Dúvida: Quando eu altero meu método Gravar, e coloco para o DAO refazer a pesquisa e preencher a lista de autores logo após persistir, tudo funciona ok.
Esse comportamento é o correto? logo após persistir o objeto eu preciso fazer uma nova consulta no banco de dados? E essa consulta deve ser dentro do meu método gravar? Pois penso que o JSF deveria cuidar disso automáticamente.
Estou fazendo algo errado?
Esse é meu método modificado no MBean do autor que faz "funcionar" :
public void gravar() {
if(this.autor.getId() == null){
autorDAO.persist(autor);
System.out.println("Gravou o Autor: " + autor.getNome());
}else{
autorDAO.merge(autor);
System.out.println("Alterou o Autor: " + autor.getNome());
}
this.autores = autorDAO.obterTodosAutores();
clear();
//return "livro?faces-redirect=true";
}
Valeu!