Problemas ao tentar salvar cadastro em JSF

Bom dia, tenho uma página que realiza o cadastro de Dentistas através do p:dialog, porém ao clicar no button
cadastrar ele mostra o erro: Target Dentista.pessoaFisica.nome unreachable, return null.

  Então tentei depurar o meu ManagedBean (DentistaMBImpl) na action salvar(), porém essa action nem está sendo chamada, creio que o erro acontece
  antes mesmo de chamar a action salvar(). 
  
  Veja como está meu p:dialog para salvar: (Desconsidere erros de sintaxe, pois estou fazendo no notepad o código, meu código real não está 
  aqui comigo no momento, mas posso garantir que o problema não é sintaxe)
  [code]
   <h:form>
   	<h:outputText value="Nome" />
   	<p:inputText value="#{dentistaMB.pessoa.pessoaFisica.nome} />
   
   	<p:commandButton actionListener="#{dentistaMB.salvar()}" value="Salvar" />
   </h:form>
  [/code]

Deve ser NullPointerException, não?

Ou o objeto “pessoa” ou o objeto “pessoaFisica” devem estar retornando null.>

Opa, desculpa o certo é o código abaixo

<p:inputText value="#{dentistaMB.dentista.pessoaFisica.nome} />    

Mas de qualquer forma continua retornando null, Target pessoaFisica unreachable.

Se eu mudo para o código abaixo:

<p:inputText value="#{dentistaMB.dentista.cro} />    

Ele diz: Target dentista unreachable, return null

Então o “dentista” deve também estar retornando null. Tenta pensar da seguinte forma. Com esse binding que você fez, o JSF por trás faz um:

E se a primeira chamada “getDentista()” retorna null, é óbvio que “null.getCro()” vai disparar NullPointerException. Só para atestar que é esse o problema, inicializa o dentista com um “new Dentista()” e vê se o problema continua a acontecer.

Vou testar aqui e ver se funciona.

[quote=rodrigo.uchoa]Então o “dentista” deve também estar retornando null. Tenta pensar da seguinte forma. Com esse binding que você fez, o JSF por trás faz um:

E se a primeira chamada “getDentista()” retorna null, é óbvio que “null.getCro()” vai disparar NullPointerException. Só para atestar que é esse o problema, inicializa o dentista com um “new Dentista()” e vê se o problema continua a acontecer.[/quote]
Errado. Se o objeto dentista, retornado pelo método getDentista() é nulo, ele não possui um método getCro(). O problema é que você não instanciou a variável dentista, do managed bean dentistaMB.

Apesar de eu não ter afirmado que null possuía um método “getCro()”, conceitualmente você está certo :slight_smile:

Bom, depois de muito procurar e ler descobri que se eu colocar “immediate = true” no meu commandButton a action salvar é chamada normalmente.

Tem mais uma coisa que resolveu o problema do: “Target unreachable”.

Se você tem uma Classe Dentista com um objeto pessoaFisica dentro, você deve inicializar o objeto pessoaFisica no construtor da classe Dentista.

 public Dentista(){
  pessoaFisica = new PessoaFisica();
}

Isso resolveu meu problema.

Isso vai funcionar porque a fase “Update Model Values” do JSF é pulada. Mas cuidado que pode ter consequências desastrosas para a operação que você quer efetuar. Em um botão de “salvar” por exemplo, não faz sentido usar “immediate = true”.

É uma maneira de fazer sim. As vezes não é muito legal iniciar direto no construtor da entidade, pois pode causar efeitos indesejáveis quando se está usando cascade no Hibernate/JPA. Em um cenário onde você deseja gravar um dentista com o atributo pessoaFisica null, se o cascade estiver habilitado para esse atributo pode ser que o hibernate tente gravar a pessoaFisica vazia, já que o atributo não vai estar null. Você vai ter que ficar lembrando de atribuir null ao atributo antes de gravar.

Bom, eu sei que pessoaFisica nunca poderá ser NULL. Isso porque todo Dentista é uma pessoaFisica.

Mas para seguir boas práticas de desenvolvimento, qual o local ideial para se inicializar essas propriedades e não pegar um “Target Unreachabled” no JSF ?

[quote]Bom, eu sei que pessoaFisica nunca poderá ser NULL. Isso porque todo Dentista é uma pessoaFisica.

Mas para seguir boas práticas de desenvolvimento, qual o local ideial para se inicializar essas propriedades e não pegar um “Target Unreachabled” no JSF ?[/quote]
Acho que pro seu caso, como você fez está de bom tamanho. Outra opção seria por exempo inicializar esses valores dentro do managed bean, em um método anotado com @PostContruct. Mas não quis dizer que o que você fez ta errado não.

Pois é, li a respeito do PostConstruct e acho uma boa saída também, até para padronizar os próximos que virão.

Bom, é isso mesmo, obrigado pela ajuda rodrigo.uchoa.