NullPointerException

Olá pessoal,

Estou fazendo um cadastro de cliente, e existe um campo onde eu verifico se é pessoa física ou jurídica. Se é pessoa física, aparece um inputMask com o CPF, se for jurídica aparece um inputMask com o CNPJ. Ambos salvam na mesma String documentoReceitaFederal.

Entretanto, quando clico em salvar está dando NullPointerException. Já tentei de tudo mas não estou achando o erro.

Seguem os códigos:

Cliente.java:

package br.com.rbg.pedidovenda.model;

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

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.NotBlank;

import com.mysql.cj.api.mysqla.result.Resultset.Type;

@Entity
@Table(name = "cliente")
public class Cliente implements Serializable {

	private static final long serialVersionUID = 1L;

	private Long id;
	private String nome;
	private String email;
	private String documentoReceitaFederal;
	private TipoPessoa tipo;
	private List<Endereco> enderecos = new ArrayList<>();
	
	@Id
	@GeneratedValue
	public Long getId() {
		return id;
	}
	
	public void setId(Long id) {
		this.id = id;
	}
	
	@NotBlank @Size(max = 100)
	@Column(nullable = false, length = 100)
	public String getNome() {
		return nome;
	}
	
	public void setNome(String nome) {
		this.nome = nome;
	}
	
	@NotBlank @Size(max = 255)
	@Column(nullable = false, length = 255)
	public String getEmail() {
		return email;
	}
	
	public void setEmail(String email) {
		this.email = email;
	}
	
	@NotBlank @Size(max = 20)
	@Column(name = "doc_receita_federal", nullable = false)
	public String getDocumentoReceitaFederal() {
		return documentoReceitaFederal;
	}
	
	public void setDocumentoReceitaFederal(String documentoReceitaFederal) {
		this.documentoReceitaFederal = documentoReceitaFederal;
	}
	
	@NotNull
	@Enumerated(EnumType.STRING)
	@Column(nullable = false, length = 10)
	public TipoPessoa getTipo() {
		return tipo;
	}

	public void setTipo(TipoPessoa tipo) {
		this.tipo = tipo;
	}
	
	@OneToMany(mappedBy = "cliente", cascade = CascadeType.ALL)
	public List<Endereco> getEnderecos() {
		return enderecos;
	}

	public void setEnderecos(List<Endereco> enderecos) {
		this.enderecos = enderecos;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Cliente other = (Cliente) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
		
}

CadastroClienteBean.java:

package br.com.rbg.pedidovenda.controller;

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

import javax.faces.bean.ManagedBean;
import javax.faces.model.SelectItem;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;

import br.com.rbg.pedidovenda.model.Cliente;
import br.com.rbg.pedidovenda.model.Endereco;
import br.com.rbg.pedidovenda.model.TipoPessoa;
import br.com.rbg.pedidovenda.service.CadastroClienteService;
import br.com.rbg.pedidovenda.util.jsf.FacesUtil;

@ManagedBean
@ViewScoped
public class CadastroClienteBean implements Serializable {

	private static final long serialVersionUID = 1L;
	
	@Inject
	private CadastroClienteService cadastroClienteService;
			
	private Cliente cliente;
	private Endereco endereco = new Endereco();	
	
	private void limpar() {
		cliente = new Cliente();
		endereco = new Endereco();
	}
		
	public CadastroClienteBean() {
		limpar();
	}
			
	public void salvar() {
		System.out.println(this.cliente.getNome() + " " + this.cliente.getTipo() + " " + this.cliente.getDocumentoReceitaFederal() + " " + this.cliente.getEmail());
		this.cliente = cadastroClienteService.salvar(this.cliente);
		limpar();
		
		FacesUtil.addInfoMessage("Cliente salvo com sucesso!");
	}
	
	public boolean isEditando() {
		return this.cliente.getId() != null;
	}
			
	public CadastroClienteService getCadastroClienteService() {
		return cadastroClienteService;
	}

	public void setCadastroClienteService(CadastroClienteService cadastroClienteService) {
		this.cadastroClienteService = cadastroClienteService;
	}
	
	public Cliente getCliente() {
		return cliente;
	}	
	
	public void setCliente(Cliente cliente) {
		this.cliente = cliente;
	}
	
	public Endereco getEndereco() {
		return endereco;
	}

	public void setEndereco(Endereco endereco) {
		this.endereco = endereco;
	}
			
}

CadastroCliente.xhtml:

<ui:composition template="/WEB-INF/template/LayoutPadrao.xhtml"
    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"
    xmlns:o="http://omnifaces.org/ui" >

	<ui:define name="titulo">Novo cliente</ui:define>

	<ui:define name="corpo">
			
		<h:form id="frmCadastroCliente">
			<h1>#{cadastroClienteBean.editando ? 'Edição de cliente' : 'Novo cliente'}</h1>
		
			<p:messages autoUpdate="true" closable="true" />
			
			<p:toolbar style="margin-top: 10px" >
				<p:toolbarGroup>
					<p:button value="Novo" outcome="/clientes/CadastroCliente.xhtml" />
					<p:commandButton id="salvar" value="Salvar" action="#{cadastroClienteBean.salvar()}" />
				</p:toolbarGroup>
			
				<p:toolbarGroup align="right">
					<p:button value="Pesquisa" outcome="/clientes/PesquisaClientes.xhtml" />
				</p:toolbarGroup>
			</p:toolbar>
		
			<p:panelGrid id="pnlCadastroNome" columns="2" style="width: 100%; margin-top: 20px" columnClasses="rotulo, campo" >
				<p:outputLabel for="nome" value="Nome" />
				<p:inputText id="nome" value="#{cadastroClienteBean.cliente.nome}" size="60" maxlength="80" />
			</p:panelGrid>
			
			<p:panelGrid id="pnlCadastroTipo" columns="2" style="width: 100%; margin-top: 20px" columnClasses="rotulo, campo" >
				<p:outputLabel value="Tipo" for="tipo" />
				<p:selectOneRadio id="tipo" required="false" value="#{cadastroClienteBean.cliente.tipo}" >
					<f:selectItem itemLabel="Física" itemValue="FISICA" />
					<f:selectItem itemLabel="Jurídica" itemValue="JURIDICA" />
					<p:ajax event="change" process="@this" update=":frmCadastroCliente:pnlCadastroTipo"/>
				</p:selectOneRadio>
				
				<p:outputLabel value="CNPJ" for="cnpj" rendered="#{cadastroClienteBean.cliente.tipo == 'JURIDICA'}" />
				<p:inputMask id="cnpj" mask="99.999.999/9999-99" value="#{cadastroClienteBean.cliente.documentoReceitaFederal}" 
					rendered="#{cadastroClienteBean.cliente.tipo == 'JURIDICA'}" />
				
				<p:outputLabel value="CPF" for="cpf" rendered="#{cadastroClienteBean.cliente.tipo == 'FISICA'}" />
				<p:inputMask id="cpf" mask="999.999.999-99" value="#{cadastroClienteBean.cliente.documentoReceitaFederal}" 
					rendered="#{cadastroClienteBean.cliente.tipo == 'FISICA'}" />
			</p:panelGrid>
			
			<p:panelGrid id="pnlCadastroEmail" columns="2" style="width: 100%; margin-top: 20px" columnClasses="rotulo, campo" >	
				<p:outputLabel for="email" value="E-mail" />
				<p:inputText id="email" value="#{cadastroClienteBean.cliente.email}" size="60" maxlength="80" />
			</p:panelGrid>
										
			<p:commandButton id="addEnderecoCliente" value="Adicionar endereço" style="margin-top: 20px"
				oncomplete="PF('inclusaoEndereco').show()"  />
		
			<p:dialog header="Inclusão de endereço" widgetVar="inclusaoEndereco" draggable="false"
				resizable="false" modal="false" minimizable="true" maximizable="true" >
			
				<h:form id="frmCadastroEndereco">
					<h:panelGrid id="pnlCadastroEndereco" columns="2">
						<p:outputLabel for="logradouro" value="Logradouro" />
						<p:inputText id="logradouro" value="Rua das Pedras Grandes Azuis" size="100" maxlength="110" 
							required="true" requiredMessage="Informe o logradouro." />
			
						<p:outputLabel for="numero" value="Número" />
						<p:inputText id="numero" value="1080" size="5" maxlength="5" required="true"
							requiredMessage="Informe o número." />
					
						<p:outputLabel for="complemento" value="Complemento" />
						<p:inputText id="complemento" value="apto 501" size="40" maxlength="50" />
					
						<p:outputLabel for="cep" value="CEP" />
						<p:inputText id="cep" value="88811-070" size="15" maxlength="20" required="true"
							requiredMessage="Informe o CEP." />
					
					 	<p:outputLabel for="cidade" value="Cidade" />
                    
    	                <h:panelGrid columns="3">    
        	            	<p:inputText id="cidade" value="Criciúma" required="true" 
        	            		requiredMessage="Informe a cidade." size="20" />    
                	        <p:outputLabel for="uf" value="UF" />
                    	    <p:inputText id="uf" value="SC" required="true" 
                    	    	requiredMessage="Informe a UF." size="2" />
						</h:panelGrid>
					</h:panelGrid>
				
					<p:commandButton value="Incluir" />
				</h:form>
			</p:dialog>
		
			<p:dataTable id="enderecosTable" value="#{cadastroClienteBean.cliente.enderecos}"
				var="endereco" style="margin-top: 10px" emptyMessage="Nenhum cliente encontrado."
				rows="20" paginator="true" paginatorAlwaysVisible="false" paginatorPosition="bottom" >
			
				<p:column headerText="Logradouro" style="text-align: left" >
					<h:outputText value="Rua das Pedras Grandes Azuis" />
				</p:column>
				
				<p:column headerText="Número" style="text-align: center; width: 100px" >
					<h:outputText value="1234" />
				</p:column>
				
				<p:column headerText="Complemento" style="text-align: left; width: 150px" >
					<h:outputText value="apto 1022" />
				</p:column>	
				
				<p:column headerText="CEP" style="text-align: center; width: 100px" >
					<h:outputText value="38499-533" />
				</p:column>
			
				<p:column headerText="Cidade/UF" style="text-align: left; width: 200px" >
					<h:outputText value="Uberlândia/MG" />
				</p:column>
			
				<p:column style="text-align: center; width: 100px" >
					<p:button icon="ui-icon-pencil" title="Editar" />
					<p:commandButton icon="ui-icon-trash" title="Excluir" oncomplete="PF('confirmacaoExclusao').show()" />
				</p:column>
			</p:dataTable>
		
			<p:confirmDialog header="Exclusão de endereço" message="Tem certeza que deseja excluir o endereço?" 
				widgetVar="confirmacaoExclusao"	>
				<p:button value="Não" onclick="PF('confirmacaoExclusao').hide(); return false;" />
				<p:commandButton value="Sim" oncomplete="PF('confirmacaoExclusao').hide()" />
			</p:confirmDialog>
		</h:form>
	</ui:define>
</ui:composition>

No método salvar eu coloquei um SystemOutPrint e verifiqei que o documentoReceitaFederal está salvando como null.

Alguma ideia de como solucionar isso?

Obrigado

Tente chamar o método salvar dessa forma…

action="#{cadastroClienteBean.salvar}"

E veja se seus objetos estão sendo populados…

Outra coisa, verifique os id’s dos inputMask, não teria que ser documentoReceitaFederal?

Afinal você tem uma regra, quando o cpf aparece, o cnpj some e vice-versa certo?

Nada impede dos dois terem o mesmo id, no final só um é renderizado…

Faz tempo que não mexo com JSF, mas o java não se baseia no ID do campo para popular seu objeto?