Problema com Target Unreachable returned NULL

Caros, boa tarde, mais uma vez venho solicitá-los na resolução de um problema, que pareceu simples à princípio.
Bem, tenho 3 entidades, sendo elas Doador, Receptor e Atendimento, visto que é um software para um banco de sangue,
tenho um relacionamento de um para muitos em Doador e Atendimento, onde devo ter muitos doadores para um atendimento e um para um de receptor para atendimento.

O meu problema está no momento de salvar um atendimento. Consegui persistir o doador, mas não o receptor.
A ideia é que quando possa salvar normalmente um doador, mas ao salvar um atendimento possa salvar o receptor e selecionar um conjunto de doadores para o mesmo, onde está me retornado null em receptor:

Entidade DOADOR

package br.com.agets.dominio;

import java.io.Serializable;
import java.util.Date;

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.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "doador")
public class Doador implements Serializable {

	/**
	 * Gets/sets e hash cods omitidos
	 */
	private static final long serialVersionUID = 1L;
	@Id
	@GeneratedValue
	private Long id;

	@ManyToOne
	@JoinColumn(name = "atendimento_id")
	private Atendimento atendimento;

	@Column(name = "nomeDoador")
	private String nomeDoador;

	@Column(name = "tipoHemoDerivados")
	@Enumerated(EnumType.STRING)
	private TipoHemoderivado tipoHemo;

	@Column(name = "tipoSanguineo")
	@Enumerated(EnumType.STRING)
	private TipoSanguineo tipoSanguineo;

	@Column(name = "dataEntrada")
	@Temporal(TemporalType.DATE)
	private Date dataEntrada;

	@Column(name = "numDoacao")
	private String numeroDoacao;

	@Column(name = "produto")
	private String produto;

	@Column(name = "volume")
	private String volume;

	@Column(name = "PAI")
	private String PAI;

	@Column(name = "sifilis", insertable = false, length = 13)
	private String sifilis;

	@Column(name = "chagas", insertable = false, length = 13)
	private String chagas;

	@Column(name = "epatiteB", insertable = false, length = 13)
	private String epatiteB;

	@Column(name = "epatiteC", insertable = false, length = 13)
	private String epatiteC;

	@Column(name = "HIV", insertable = false, length = 13)
	private String HIV;

	@Column(name = "HTLV", insertable = false, length = 13)
	private String HTLV;

	@Column(name = "destino")
	@Enumerated(EnumType.STRING)
	private TipoDestino destino;

	@Column(name = "Obs")
	private String Observacoes;

	}

Entidade receptor

package br.com.agets.dominio;

import java.io.Serializable;

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.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "receptor")
public class Receptor implements Serializable {

	/**
	 *  Gets/sets e hash cods omitidos
	 */
	private static final long serialVersionUID = 1L;
	@Id
	@GeneratedValue
	private Long id;

	@Column(name = "nomeReceptor")
	private String nomeReceptor;

	@Column(name = "nomeHospital")
	private String nomeHospital;

	@Column(name = "numProntuario")
	private String numProntuario;

	@Column(name = "tipoSanguineo")
	@Enumerated(EnumType.STRING)
	private TipoSanguineo tipoSanguineo;

	@OneToOne(mappedBy = "receptor")
	private Atendimento atendimento;

	@Column(name = "RH")
	private String RH;

	@Column(name = "PAI")
	private String PAI;

	@Column(name = "numDoacao")
	private String numDoacao;

	@Column(name = "hemoDerivados")
	@Enumerated(EnumType.STRING)
	private TipoHemoderivado tipoHemo;

	@Column(name = "volume")
	private String volume;

Entidade atendimento

package br.com.agets.dominio;

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

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "atendimento")
public class Atendimento implements Serializable {

	/**
	 * Gets e sets omitidos
	 */
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue
	private Long id;

	@OneToMany(mappedBy = "atendimento", targetEntity = Doador.class, fetch = FetchType.LAZY)
	private List<Doador> doadores;

	public List<Doador> getDoadores() {
		return doadores;
	}

	public void setDoadores(List<Doador> doadores) {
		this.doadores = doadores;
	}

	@OneToOne
	@JoinColumn(name = "receptor_id", nullable = false)
	private Receptor receptor;

	@Column(name = "dataAtendimento")
	@Temporal(TemporalType.DATE)
	private Date dataAtendimento;

	@Column(name = "numOrdem")
	private String numeroOrdem;

	@Column(name = "testeCompatibilidade")
	private boolean testeCompatibilidade;

ManagedBean Atendimento

package br.com.agets.visao;

import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;

import br.com.agets.dominio.Atendimento;
import br.com.agets.dominio.Doador;
import br.com.agets.dominio.TipoHemoderivado;
import br.com.agets.dominio.TipoSanguineo;
import br.com.agets.negocio.AtendimentoService;
import br.com.agets.negocio.DoadorService;
import br.com.agets.negocio.RegraNegocioException;

@ManagedBean(name = "atendimentoBean")
@SessionScoped
public class AtendimentoBean {

	private Atendimento atendimentoEdicao;
	private List<Atendimento> atendimentos = new ArrayList<Atendimento>();
	private List<SelectItem> tiposHemoderivados;
	private List<SelectItem> tiposSanguineos;
	private List<SelectItem> doadores;

	public String inicializar() {
		this.atendimentoEdicao = new Atendimento();
		this.tiposHemoderivados = null;
		this.tiposSanguineos = null;
		this.atendimentos = null;
		this.doadores = null;
		return "incluirAtendimento";
	}

	public void salvar(ActionEvent event) {
		FacesContext context = FacesContext.getCurrentInstance();
		try {
			new AtendimentoService().salvar(this.atendimentoEdicao);
			this.atendimentoEdicao = new Atendimento();
			FacesMessage msg = new FacesMessage("Atendimento Cadastrado com sucesso!");
			msg.setSeverity(FacesMessage.SEVERITY_INFO);
			context.addMessage(null, msg);
		} catch (RegraNegocioException e) {
			context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), e.getMessage()));
		} catch (Exception e) {
			e.printStackTrace();
			FacesMessage msg = new FacesMessage("Erro inesperado ao cadastrar atendimento! ");
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			context.addMessage(null, msg);
		}
	}

	public void excluir() {
		FacesContext context = FacesContext.getCurrentInstance();
		try {
			new AtendimentoService().excluir(this.atendimentoEdicao);
			this.atendimentos.remove(this.atendimentoEdicao);
			FacesMessage msg = new FacesMessage("Atendimento excluído com sucesso!");
			msg.setSeverity(FacesMessage.SEVERITY_INFO);
			context.addMessage(null, msg);
		} catch (RegraNegocioException e) {
			context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), e.getMessage()));
		} catch (Exception e) {
			e.printStackTrace();
			FacesMessage msg = new FacesMessage("Erro inesperado ao excluir atendimento!");
			msg.setSeverity(FacesMessage.SEVERITY_ERROR);
			context.addMessage(null, msg);
		}
	}

	public void consultar(ActionEvent event) {
		this.atendimentos = new AtendimentoService().listarTodos();

	}

	public List<SelectItem> getDoadores() {
		if (this.doadores == null) {
			this.doadores = new ArrayList<SelectItem>();
			List<Doador> doadores = new DoadorService().listarTodos();
			this.doadores.add(new SelectItem(null, "Selecione"));
			for (Doador doador : doadores) {
				this.doadores.add(new SelectItem(doador.getNomeDoador()));

			}
		}
		return this.doadores;
	}

	public List<SelectItem> getTiposHemoderivados() {
		if (this.tiposHemoderivados == null) {
			this.tiposHemoderivados = new ArrayList<SelectItem>();
			this.tiposHemoderivados.add(new SelectItem(null, "Selecione"));
			for (TipoHemoderivado tipos : TipoHemoderivado.values()) {
				this.tiposHemoderivados.add(new SelectItem(tipos.toString()));
			}
		}
		return tiposHemoderivados;
	}

	public List<SelectItem> getTiposSanguineos() {
		if (this.tiposSanguineos == null) {
			this.tiposSanguineos = new ArrayList<SelectItem>();
			this.tiposSanguineos.add(new SelectItem(null, "Selecione"));
			for (TipoSanguineo tipos : TipoSanguineo.values()) {
				this.tiposHemoderivados.add(new SelectItem(tipos.toString()));
			}
		}
		return tiposSanguineos;
	}

	public Atendimento getAtendimentoEdicao() {
		return atendimentoEdicao;
	}

	public void setAtendimentoEdicao(Atendimento atendimentoEdicao) {
		this.atendimentoEdicao = atendimentoEdicao;
	}

	public List<Atendimento> getAtendimentos() {
		return atendimentos;
	}

	public void setAtendimentos(List<Atendimento> atendimentos) {
		this.atendimentos = atendimentos;
	}

	public void setTiposHemoderivados(List<SelectItem> tiposHemoderivados) {
		this.tiposHemoderivados = tiposHemoderivados;
	}

	public void setTiposSanguineos(List<SelectItem> tiposSanguineos) {
		this.tiposSanguineos = tiposSanguineos;
	}

	public void setDoadores(List<SelectItem> doadores) {
		this.doadores = doadores;
	}
}

Página incluir Atendimento, onde tenho meus problemas

<?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:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:a4j="http://richfaces.org/a4j"
	xmlns:rich="http://richfaces.org/rich">
<h:head>
	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"></meta>
	<title>Cadastro de atendimentos</title>
</h:head>
<h:body>
	<f:view>
		<h:form>
			<h1>
				<h:outputText value="Cadastro de atendimentos"></h:outputText>
			</h1>

			<a4j:poll render="mensagem" interval="5000"></a4j:poll>

			<h:messages layout="table" showSummary="true" showDetail="false"
				id="mensagem" globalOnly="true" styleClass="msgErro"
				infoClass="msgInfo" style="font-weight: bold" />

			<h:panelGrid columns="2">

				<h:outputLabel value="Código:"
					rendered="#{atendimentoBean.atendimentoEdicao.id !=null}" />
				<h:panelGroup
					rendered="#{atendimentoBean.atendimentoEdicao.id !=null}">
					<h:inputText required="true" id="codigo"
						value="#{atendimentoBean.atendimentoEdicao.id}"
						label="Código do atendimento" disabled="true" />
					<h:message for="codigo" showSummary="true" showDetail="false"></h:message>
				</h:panelGroup>

				<h:outputLabel value="Data de Entrada" />
				<h:panelGroup>
					<rich:calendar id="dataEntrada" enableManualInput="true"
						value="#{atendimentoBean.atendimentoEdicao.dataAtendimento}"
						required="true" requiredMessage="Esse campo é obrigatório"
						locale="pt_BR" datePattern="dd/MM/yyyy">
						<h:message for="dataEntrada" showSummary="true" showDetail="false"></h:message>
					</rich:calendar>
				</h:panelGroup>


				<h:outputLabel value="Número de ordem" />
				<h:panelGroup>
					<h:inputText id="numOrdem"
						value="#{atendimentoBean.atendimentoEdicao.numeroOrdem}"
						required="true" size="40"
						requiredMessage="Este campo é obrigatório" />
					<h:message for="numOrdem" showSummary="true" showDetail="false"
						styleClass="msgErro"></h:message>
				</h:panelGroup>

				<h:outputLabel value="Teste de compatibilidade" />
				<h:panelGroup>
					<h:selectOneRadio id="compatibilidade" required="true"
						requiredMessage="Este campo é obrigatório"
						value="#{atendimentoBean.atendimentoEdicao.testeCompatibilidade}"
						label="Teste de compatibilidade" layout="pageDirection">
						<f:selectItem itemValue="true" itemLabel="Aprovado" />
						<f:selectItem itemValue="false" itemLabel="Reprovado" />
					</h:selectOneRadio>
					<h:message for="compatibilidade" showSummary="true"
						showDetail="false" styleClass="msgErro"></h:message>
				</h:panelGroup>

				<h:outputLabel value="Tipo Sanguíneo" />
				<h:panelGroup>
					<h:selectOneMenu id="tipoSang" required="true"
						requiredMessage="Este campo é obrigatório"
						value="#{atendimentoBean.atendimentoEdicao.receptor.tipoSanguineo}"
						label="TIpo de Hemoderivados do doador">
						<f:selectItems value="#{doadorBean.tiposSanguineos}" />
					</h:selectOneMenu>
					<h:message for="tipoSang" showSummary="true" showDetail="false"
						styleClass="msgErro"></h:message>
				</h:panelGroup>


				<h:outputLabel value="Doadores" />
				<h:panelGroup>
					<h:selectManyCheckbox>
						<f:selectItems value="#{atendimentoBean.doadores}"></f:selectItems>
					</h:selectManyCheckbox>
				</h:panelGroup>

				<h:outputLabel value="Nome do Receptor" />
				<h:panelGroup>
					<h:inputText id="nomeReceptor"
						value="#{atendimentoBean.atendimentoEdicao.receptor.nomeReceptor}"
						required="true" size="40"
						requiredMessage="Este campo é obrigatório"
						onkeyup="this.value = this.value.toUpperCase();" />
					<h:message for="nomeReceptor" showSummary="true" showDetail="false"
						styleClass="msgErro"></h:message>
				</h:panelGroup>

				<h:outputLabel value="Nome do Hospital" />
				<h:panelGroup>
					<h:inputText id="nomeHospital"
						value="#{atendimentoBean.atendimentoEdicao.receptor.nomeHospital}"
						required="true" size="40"
						onkeyup="this.value = this.value.toUpperCase();"
						requiredMessage="Este campo é obrigatório" />
					<h:message for="nomeHospital" showSummary="true" showDetail="false"
						styleClass="msgErro"></h:message>
				</h:panelGroup>

				<h:outputLabel value="Número do prontuário" />
				<h:panelGroup>
					<h:inputText id="numProntuario"
						value="#{atendimentoBean.atendimentoEdicao.receptor.numProntuario}"
						required="true" size="40"
						requiredMessage="Este campo é obrigatório" />
					<h:message for="numProntuario" showSummary="true"
						showDetail="false" styleClass="msgErro"></h:message>
				</h:panelGroup>

				<h:outputLabel value="RH" />
				<h:panelGroup>
					<h:selectOneMenu id="rh" required="true"
						requiredMessage="Este campo é obrigatório"
						value="#{atendimentoBean.atendimentoEdicao.receptor.RH}"
						label="TIpo de Hemoderivados do doador">
						<f:selectItem itemLabel="RH+"
							itemValue="#{atendimentoBean.atendimentoEdicao.receptor.RH}" />
						<f:selectItem itemLabel="RH-"
							itemValue="#{atendimentoBean.atendimentoEdicao.receptor.RH}" />
					</h:selectOneMenu>
					<h:message for="rh" showSummary="true" showDetail="false"
						styleClass="msgErro"></h:message>
				</h:panelGroup>

				<h:outputLabel value="P.A.I." />
				<h:panelGroup>
					<h:inputText id="pai"
						value="#{atendimentoBean.atendimentoEdicao.receptor.PAI}"
						required="true" size="40"
						requiredMessage="Este campo é obrigatório" />
					<h:message for="pai" showSummary="true" showDetail="false"
						styleClass="msgErro"></h:message>
				</h:panelGroup>
			</h:panelGrid>


			<h:commandButton value="Salvar"
				actionListener="#{atendimentoBean.salvar}"></h:commandButton>
			<h:commandButton value="Voltar" immediate="true" action="menu"></h:commandButton>
		</h:form>
	</f:view>
</h:body>
</html>

Este é meu erro

javax.servlet.ServletException: /incluirAtendimento.xhtml @99,58 value="#{atendimentoBean.atendimentoEdicao.receptor.nomeReceptor}": Target Unreachable, 'receptor' returned null
javax.faces.webapp.FacesServlet.service(FacesServlet.java:521)

javax.el.PropertyNotFoundException: /incluirAtendimento.xhtml @99,58 value="#{atendimentoBean.atendimentoEdicao.receptor.nomeReceptor}": Target Unreachable, 'receptor' returned null
com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:100)

Espero que possam me ajudar.

Ninguém?

Olá,

olha… estou aprendendo ainda, então talvez possa falar besteira… mas ao que parece é que seu objeto ‘receptor’ não esta sendo instanciado, e por isso nulo.
eu costumo fazer isso no get do objeto… tente algo assim:

public Atendimento getAtendimentoEdicao() {
        if(atendimentoEdicao == null){
                atendimentoEdicao = new Atendimento();
        }  
        return atendimentoEdicao;  
    }

pcSantana, tudo bem?
Realmente, talvez devesse, mas veja:

Para inicar o bean, carrego-o assim:

<h:commandLink action="#{atendimentoBean.inicializar}">
	<h:outputText value="Cadastro de Atendimento" />
</h:commandLink>

e no bean, o método inicializar:

[code]public class AtendimentoBean {

private Atendimento atendimentoEdicao;
private List<Atendimento> atendimentos = new ArrayList<Atendimento>();
private List<SelectItem> tiposHemoderivados;
private List<SelectItem> tiposSanguineos;
private List<SelectItem> doadores;

public String inicializar() {
	this.atendimentoEdicao = new Atendimento();
	this.tiposHemoderivados = null;
	this.tiposSanguineos = null;
	this.atendimentos = null;
	this.doadores = null;
	return "incluirAtendimento";
}[/code]

Ou seja, não veria porquê não funcionar, concorda?

O que sugere?

veja se de repente vc não está cometendo esse mesmo erro:

http://www.guj.com.br/java/251164-resolvido-uma-duvida-muito-idiota-target-unreachable-returned-null

Acho que não, mas é verdade que a entidade está vazia, mas… preciso salvar nela… e ela acessará a outra.

O melhor é quando você marca breakpoints e debuga - passa direto…kkk

smnj, blz?

Uma dúvida: instanciou o ojeto receptor? Porque não percebi isso…
E o problema acontece quando você executa qual método? salvar?

Tudo bem, Alan?
tudo o que fiz, postei, se acaso não instanciei, me ensine como fazê-lo, por favor?
Exatamente, não dá problemas diferentes de quando tento persistir atendimentos a não ser que o objeto ausente é o receptor, mas quando tento os dois dá TargetUNreachable returned null para receptor.

Faria isso no outro objeto?
Diz entre receptor e atendimento?
Acho que talvez posso estar errando aí.

Como fazê-lo Alan?

smnj, ainda não tive a oportunidade de trabalhar com este tipo de situação (1x1) em mapeamento JPA, porém, creio que você deverá persistir tanto em o Receptor em Atendimento quanto o Atendimento em Receptor.

E, pode ser descuido meu, mas também não vi você passando o receptor para que o JPA faça a persistencia…
Espero que seja um caminho…

Eu talvez tenha dúvidas de como fazer isso:

[quote]E, pode ser descuido meu, mas também não vi você passando o receptor para que o JPA faça a persistência[/quote]…

Concordo com você em parte, mas veja que Posso ter vários doadores, e eles não vão ter relação no momento do cadastro dos mesmos com o atendimento, só mesmo durante uma doação usaria uma lista de doadores para um atendimento, e também, teria apenas um receptor, que por sua vez teria um conjunto de doadores para atendimento.
Então não creio que preciso persistir um doador juntamente com atendimento. mas precisaria com certeza de persistir uma lista de doadores e um receptor para um atendimento.

Me ensine a fazer isso:

Quando vc faz issso:

public void salvar(ActionEvent event) { FacesContext context = FacesContext.getCurrentInstance(); try { new AtendimentoService().salvar(this.atendimentoEdicao); . . . } }
De alguma forma vc tem que setar antes o receptor dentro do atendimentoEdicao
Agora como? Dependerá de como está fazendo isso na sua página…

Isso não seria o bastante, Alan?
No receptor:

@OneToOne(mappedBy = "receptor") private Atendimento atendimento;

No atendimento:

@OneToOne @JoinColumn(name = "receptor_id", nullable = false) private Receptor receptor;

veja bem, o atendimento leva o bendito receptor em seu bean, e quando salvo o bendito atendimento não teoricamente teria que fazê-lo, visto que o atendimento carrega um receptor:

@OneToOne @JoinColumn(name = "receptor_id", nullable = false) private Receptor receptor;

Vou ver meu banco óia que beleza:

org.hibernate.PropertyValueException: not-null property references a null or transient value: br.com.agets.dominio.Atendimento.receptor

Apesar de esse detalhe não estar mudando em nada, no banco não tem nada que nessa notnull.