CRUD em JSF. Problemas no Alterar

21 respostas
H

Bom dia senhores!

Estou com um problema em uma pequena aplicação que estou desenvolvendo na hora de alterar um registro. Não consigo recuperar o objeto e carregá-lo na página para alterar seus valores. Ex: Tenho um p:dataTable que possui uma coluna com 2 botões (Alterar e Excluir) e ao clicar em Alterar, deve ser mostrada a página com os dados desse registro carregados nos campos. Porém isso não acontece, a página sempre é carregada em branco. Segue o meu código:

DataTable
<p:dataTable id="planoList" rows="10" paginator="true" value="#{planoSaudeController.lista}" var="plano"
	paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}" 
	emptyMessage="Nenhum registro encontrado!">			
	<p:column>
		<f:facet name="header">
			<h:outputText value="Nome do Plano" />
		</f:facet>
		<h:outputText value="#{plano.nomePlano}" />
	</p:column>
					
	<p:column>
		<f:facet name="header">
			<h:outputText value="Descrição" />
		</f:facet>
		<h:outputText value="#{plano.descricao}" />
	</p:column>
					
	<p:column>
		<f:facet name="header">
			<h:outputText value="Ação" />
		</f:facet>
		<p:commandButton icon="ui-icon-pencil" title="Visualizar/Alterar" action="#{planoSaudeController.createUpdate}">
			<f:setPropertyActionListener value="#{plano}" target="#{planoSaudeController.planoSaude}"/>
		</p:commandButton>
		<p:commandButton icon="ui-icon-trash" title="Excluir" update="form" oncomplete="confirm.show()">
			<f:setPropertyActionListener value="#{plano}" target="#{planoSaudeController.planoSaude}" />
		</p:commandButton>
	</p:column>
				
</p:dataTable>

21 Respostas

R

Nesse metodo de update o valor de ‘planoSaude’ está nulo?

H

cara, na verdade essa action que está no dataTable ela apenas retorna uma String que irá redirecionar o usuário para a tela de alteração.

A
<h:form />

Não será esse o problema ?

R

O que eu quis dizer é:vc está instanciando esse objeto em algum momento?

H
alberthy:
<h:form />

Não será esse o problema ?

Com certeza não. O p:dataTable está dentro de um h:form só não coloquei aqui pois não achei que fosse importante. Mas segue o código completo da página:
<ui:composition template="../../resources/template/template.xhtml">

	<ui:define name="title">.: Gestão de Planos de Saúde :.</ui:define>
	<ui:define name="content">
		
		<p:panel header="Gestão de Planos de Saúde">
		
			<h:form id="searchForm">
				
				<br/>
				
				<h:panelGrid columns="3">
					<p:commandButton value="Novo Plano" icon="ui-icon-plus" action="#{planoSaudeController.createUpdate}" immediate="true"/>
					<p:inputText id="searchbox" value="#{planoSaudeController.pesquisa}" size="50"/>
					<p:commandButton value="Pesquisar" icon="ui-icon-search" update="form"/>
				</h:panelGrid>
				
				<br/>
				<br/>
				
			</h:form>	
			<h:form id="form">	
				
				
				<p:messages/>
				
				<p:dataTable id="planoList" rows="10" paginator="true" value="#{planoSaudeController.lista}" var="plano"
				paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}" 
				emptyMessage="Nenhum registro encontrado!">
				
					<p:column>
						<f:facet name="header">
							<h:outputText value="Nome do Plano" />
						</f:facet>
						<h:outputText value="#{plano.nomePlano}" />
					</p:column>
					
					<p:column>
						<f:facet name="header">
							<h:outputText value="Descrição" />
						</f:facet>
						<h:outputText value="#{plano.descricao}" />
					</p:column>
					
					<p:column>
						<f:facet name="header">
							<h:outputText value="Ação" />
						</f:facet>
						<p:commandButton icon="ui-icon-pencil" title="Visualizar/Alterar" action="#{planoSaudeController.createUpdate}">
							<f:setPropertyActionListener value="#{plano}" target="#{planoSaudeController.planoSaude}"/>
						</p:commandButton>
						<p:commandButton icon="ui-icon-trash" title="Excluir" update="form" oncomplete="confirm.show()">
							<f:setPropertyActionListener value="#{plano}" target="#{planoSaudeController.planoSaude}" />
						</p:commandButton>
					</p:column>
				
				</p:dataTable>
			
			</h:form>
			
			<h:form id="dlg">
				
				<p:confirmDialog message="Deseja realmente excluir o plano selecionado ?" widgetVar="confirm"
				header="Advertência" severity="alert">
					
					<h:panelGrid columns="2" id="display">
						
						<p:commandButton value="Sim" icon="ui-icon-check" actionListener="#{planoSaudeController.excluir}" 
						oncomplete="confirm.hide()" process="@form" update="form:planoList"/>
						<p:commandButton value="Não" icon="ui-icon-cancel" onclick="confirm.hide()" type="button" />
					
					</h:panelGrid>		
					
				</p:confirmDialog>
				
			</h:form>
		
		</p:panel>
		
	</ui:define>
	
</ui:composition>
@raf4ever Sim, eu estou instanciando o objeto no ManagedBean. Segue:
@ManagedBean
public class PlanoSaudeController {

	private PlanoSaude planoSaude = new PlanoSaude();
	private PlanoSaude planoSelecionado = new PlanoSaude();
	private List<PlanoSaude> planos = new ArrayList<PlanoSaude>(0);
	private boolean alterar = false;
	private String pesquisa;
	
	@EJB
	private PlanoSaudeBeanLocal planoBean;
	
	
	public String salvar() {
		FacesContext context = FacesContext.getCurrentInstance();
		FacesMessage message = new FacesMessage();
		
		try {
			
			if(getPlanoSaude().getId() != null) {
				
				planoBean.update(getPlanoSaude());
				message.setSummary("Plano de Saúde atualizado com sucesso!");
				message.setSeverity(FacesMessage.SEVERITY_INFO);
				context.addMessage(null, message);
				
			} else {
				
				planoBean.save(getPlanoSaude());
				message.setSummary("Plano de Saúde salvo com sucesso!");
				message.setSeverity(FacesMessage.SEVERITY_INFO);
				context.addMessage(null, message);
				
			}
			setPlanoSaude(new PlanoSaude());
			return null;

		} catch (Exception e) {
			e.printStackTrace();
			message.setSummary("Erro inesperado ao salvar Plano de Saúde!");
			message.setSeverity(FacesMessage.SEVERITY_ERROR);
			context.addMessage(null, message);			
			return null;
		}

	}
	
	public void excluir(ActionEvent event) {
		FacesContext context = FacesContext.getCurrentInstance();
		FacesMessage message = new FacesMessage();
		
		try {
			System.out.println(getPlanoSelecionado().toString());
			planoBean.delete(PlanoSaude.class, getPlanoSelecionado().getId());
			message.setSummary("Plano de Saúde excluído com sucesso!");
			message.setSeverity(FacesMessage.SEVERITY_INFO);
			context.addMessage(null, message);
		} catch (Exception e) {
			e.printStackTrace();
			message.setSummary("Erro inesperado ao excluir Plano de Saúde!");
			message.setSeverity(FacesMessage.SEVERITY_ERROR);
			context.addMessage(null, message);
		}
	}
	
	
	
	public List<PlanoSaude> getLista() {
		planos = planoBean.list(PlanoSaude.class, null, "nomePlano");
		return planos;
	}
	
	public String createUpdate() {
		return "planoCreateUpdate";
	}
	
	public String list() {
		return "planoList";
	}
	
	public PlanoSaude getPlanoSaude() {
		return planoSaude;
	}
	public void setPlanoSaude(PlanoSaude planoSaude) {
		this.planoSaude = planoSaude;
	}
	
	public List<PlanoSaude> getPlanos() {
		return planos;
	}
	public void setPlanos(List<PlanoSaude> planos) {
		this.planos = planos;
	}
	
	public boolean isAlterar() {
		return alterar;
	}
	public void setAlterar(boolean alterar) {
		this.alterar = alterar;
	}

	public PlanoSaude getPlanoSelecionado() {
		return planoSelecionado;
	}
	public void setPlanoSelecionado(PlanoSaude planoSelecionado) {
		this.planoSelecionado = planoSelecionado;
	}
	
	public String getPesquisa() {
		return pesquisa;
	}
	public void setPesquisa(String pesquisa) {
		this.pesquisa = pesquisa;
	}
	
}
R

Pra que dois h:form na página?Eu acho que isso pode ter alguma coisa a ver com o problema.

W

Cara, muitos dos problemas que eu já tive com jsf estava relacionado ao uso de dois form na página, faz em um só que deve funcionar.

H
Pessoal, removi um dos forms mas mesmo assim, ainda não consigo carregar os dados para alteração.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:p="http://primefaces.org/ui">

<ui:composition template="../../resources/template/template.xhtml">

	<ui:define name="title">.: Gestão de Planos de Saúde :.</ui:define>
	<ui:define name="content">
		
		<p:panel header="Gestão de Planos de Saúde">
		
			<h:form id="form">
				
				<br/>
				<p:messages/>
				<h:panelGrid columns="3">
					<p:commandButton value="Novo Plano" icon="ui-icon-plus" action="#{planoSaudeController.createUpdate}" immediate="true"/>
					<p:inputText id="searchbox" value="#{planoSaudeController.pesquisa}" size="50"/>
					<p:commandButton value="Pesquisar" icon="ui-icon-search" update="form"/>
				</h:panelGrid>
				
				<br/>
				<br/>				
				
				<p:dataTable id="planoList" rows="10" paginator="true" value="#{planoSaudeController.lista}" var="plano"
				paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}" 
				emptyMessage="Nenhum registro encontrado!">
				
					<p:column>
						<f:facet name="header">
							<h:outputText value="Nome do Plano" />
						</f:facet>
						<h:outputText value="#{plano.nomePlano}" />
					</p:column>
					
					<p:column>
						<f:facet name="header">
							<h:outputText value="Descrição" />
						</f:facet>
						<h:outputText value="#{plano.descricao}" />
					</p:column>
					
					<p:column>
						<f:facet name="header">
							<h:outputText value="Ação" />
						</f:facet>
						<p:commandButton icon="ui-icon-pencil" title="Visualizar/Alterar" action="#{planoSaudeController.createUpdate}">
							<f:setPropertyActionListener value="#{plano}" target="#{planoSaudeController.planoSaude}"/>
						</p:commandButton>
						<p:commandButton icon="ui-icon-trash" title="Excluir" update="form" oncomplete="confirm.show()">
							<f:setPropertyActionListener value="#{plano}" target="#{planoSaudeController.planoSaude}" />
						</p:commandButton>
					</p:column>
				
				</p:dataTable>
			
			</h:form>
			
			<h:form id="dlg">
				
				<p:confirmDialog message="Deseja realmente excluir o plano selecionado ?" widgetVar="confirm"
				header="Advertência" severity="alert">
					
					<h:panelGrid columns="2" id="display">
						
						<p:commandButton value="Sim" icon="ui-icon-check" actionListener="#{planoSaudeController.excluir}" 
						oncomplete="confirm.hide()" process="@form" update="form:planoList"/>
						<p:commandButton value="Não" icon="ui-icon-cancel" onclick="confirm.hide()" type="button" />
					
					</h:panelGrid>		
					
				</p:confirmDialog>
				
			</h:form>
		
		</p:panel>
		
	</ui:define>
	
</ui:composition>

</html>
D

Ola amigo

Porque voce nao tenta dar um update no seu form assim

<p:commandButton icon="ui-icon-pencil" title="Visualizar/Alterar" action="#{planoSaudeController.createUpdate}" update="nomeDoForm"> <f:setPropertyActionListener value="#{plano}" target="#{planoSaudeController.planoSaude}"/> </p:commandButton>

L

vamos enxugar seu código um pouco primeiro… vc não precisa usar isso [color=red]paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"[/color] o paginator=“true” já resolve tranquilo…

na hora de vc selecionar em alterar… vc ta clicando na coluna do datatable certo? vc precisar ter outras tags pra quando clicar ele atualizar os campos que vc quer… tem que ter a tag selection="#{seuObjeto}" e um onRowSelectUpdate=“idCampos” eu geralmente coloco todos os campos dentro de um h:panelGrid e defino o ID(idCampos)… e coloco as inputs dentro dele… ai quando clico na linha que quero… ele fecha o dataTtable e joga nos campos a linha que eu cliquei…

e use actionListener de preferencia…

H

lordaj:

na hora de vc selecionar em alterar… vc ta clicando na coluna do datatable certo? vc precisar ter outras tags pra quando clicar ele atualizar os campos que vc quer… tem que ter a tag selection="#{seuObjeto}" e um onRowSelectUpdate=“idCampos” eu geralmente coloco todos os campos dentro de um h:panelGrid e defino o ID(idCampos)… e coloco as inputs dentro dele… ai quando clico na linha que quero… ele fecha o dataTtable e joga nos campos a linha que eu cliquei…

e use actionListener de preferencia…


Poderia dar um exemplo cara ? Não entendi muito bem o que vc quis dizer.

O método action no meu código apenas redireciona o usuário pra tela de alteração, então não vejo pq de se usar actionListener. Ou estou enganado ?

L

eu faço assim…

<p:dialog width=“400” showEffect=“bounce” header=“Resultados” widgetVar=“DialogAT” id=“DialogAT” >

<p:dataTable paginator="true"
                                     value="#{leisMB.listaLeis}" selection="#{leisMB.leis}"
                                     selectionMode="single" id="tblDT" var="VARCodAT" rows="4"
                                     onRowSelectUpdate="GridAT" >

                            <p:column style="text-align: center;" >
                                <f:facet name="header">
                                    <h:outputText  value="Codigo" />
                                </f:facet>
                                <h:outputText value="#{VARCodAT.codigo}" />
                            </p:column>

                            <p:column>
                                <f:facet name="header">
                                    <h:outputText  value="Título" />
                                </f:facet>
                                <h:outputText value="#{VARCodAT.titulo}" />
                            </p:column>
                        </p:dataTable>

                    </p:dialog>

axo q vc nao precisa redirecionar… quando vc fizer a pesquisa… vc joga o resultado em uma dialog igual essa q to mostrando… ai ela vai ter o resultado no datatable… ai quando vc clicar 2x em alguma das linhas q ele retornou da pesquisa… vc manda atualizar os campos que vc quer sacou? nao precisa jogar pra oouuuuutra página… dentro dessa ai basta criar uma dialog… q vai trazer o resultado… quando clicar 2x já era… fecha a dialog… e preenche os campos… tendeu? vc pode colocar tudo isso na página de atualização mesmo… pesquisa… seleciona e preenche os campos., ai evita isso de precisar redirecionar.

H

Alguém ?

H

Pessoal, me dêem uma força pois só tenho mais uma semana para terminar esse projeto.

Desde já agradeço.

R

hugo.hlcxcx:
Pessoal, me dêem uma força pois só tenho mais uma semana para terminar esse projeto.

Desde já agradeço.

Se vc botar um breakpoint no metodo createUpdate(),qual é o valor de ‘planoSaude’?

R

Creio que o problema esteja aqui:

private PlanoSaude planoSaude = new PlanoSaude();

Devido o teu ManagedBean estar com escopo de requisição,quando vc chama o createUpdate o estado do objeto é resetado,dai a página aparecer em branco.

A

Tenta anotar seu MB como:

@viewScoped

pode ser que funfe como o amigo ai em cima disse!..

vlw

D

porra,

é foda, li o tópico inteiro até fiquei curioso pra saber se resolveu
e o topico morreu sem solução…

afff isso desanima! Senhor autor, poderia por favor dar o feedback?
Será de grande contribuição

flw

V

Também estou com esse mesmo problema

up

R

Vo posta um exemplo de como uso para fazer isso, clicar no botao do datatable e abrir uma pagina para alterar:

<p:column sortBy="#{bean.descricao}"> <f:facet name="header">#{messages['projeto.label.descricao']}</f:facet> <h:commandLink action="#{projetoListMB.getNextView}" actionListener="#{projetoListMB.clear}"> <h:outputText value="#{bean.descricao}" /> <f:param name="id" value="#{bean.idProjeto}" /> </h:commandLink> </p:column>

  1. Uso o <f:facet> somente para dar um nome para coluna, mas isto pode ser substituido acrescentando um header, um proprio atributo da tag <p:column>
  2. Uso o commandLink, mas voces podem ficar a vontade para usar commandButton, dentro da tag commandLink ponho um texto, e ponho um <f:param>, e é aqui que ta o segredo, ao clicar no commandLink, ele passa o id para o bean, que por sua vez carrega a pagina h:commandLink action="#{projetoListMB.getNextView}" setada no meu proprio bean. lembrando que bean é o var do datatable, exemplo:
<p:dataTable id="list" var="bean" value="#{projetoListMB.resultList}">
C

Ola hugo.hlcxcx

Lá no se Bean coloque o escopo @RequestScoped,
segue um exemplo:

@ManagedBean
@RequestScoped
public class PaisBean implements Serializable{

Criado 7 de fevereiro de 2012
Ultima resposta 17 de jul. de 2013
Respostas 21
Participantes 11