java – JPA hibernate error = foreign key is returning null

Question:

After a long time of research, without success, I decided to post my question.

I'm using JPA/Hibernate and I have two tables: a Pessoa and an Funcionário .

The error occurs when I'm going to save my data, the pessoa_id foreign key is empty, ie null .

I will post my code below in hopes of a solution:

Table/Class = person.java:

package br.com.teste.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.NotEmpty;

@Entity
@Table(name = "pessoa")
public class Pessoa implements Serializable {
    private static final long serialVersionUID = 1L;
    Long id;

    private String nome;
    private String endereco;
    private String numero;
    private String complemento;
    private String bairro;
    private String cidade;
    private String estado;
    private String cep;


    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @NotEmpty
    @Size(max = 100)
    @Column(length = 100, nullable = false)
    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    @NotEmpty
    @Size(max = 100)
    @Column(length = 100, nullable = false)
    public String getEndereco() {
        return endereco;
    }

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

    @NotEmpty
    @Size(max = 6)
    @Column(length = 6, nullable = false)
    public String getNumero() {
        return numero;
    }

    public void setNumero(String numero) {
        this.numero = numero;
    }


    //@NotEmpty
    @Size(max = 50)
    @Column(length = 50, nullable = false)
    public String getComplemento() {
        return complemento;
    }

    public void setComplemento(String complemento) {
        this.complemento = complemento;
    }

    @NotEmpty
    @Size(max = 30)
    @Column(length = 30, nullable = false)
    public String getBairro() {
        return bairro;
    }

    public void setBairro(String bairro) {
        this.bairro = bairro;
    }

    @NotEmpty
    @Size(max = 30)
    @Column(length = 30, nullable = false)
    public String getCidade() {
        return cidade;
    }

    public void setCidade(String cidade) {
        this.cidade = cidade;
    }

    @NotEmpty
    @Size(max = 2)
    @Column(length = 2, nullable = false)
    public String getEstado() {
        return estado;
    }

    public void setEstado(String estado) {
        this.estado = estado;
    }

    @NotEmpty
    @Size(max = 9)
    @Column(length = 9, nullable = false)
    public String getCep() {
        return cep;
    }

    public void setCep(String cep) {
        this.cep = cep;
    }


    @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;
        Pessoa other = (Pessoa) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }
}

Table/Class = employee.java:

package br.com.teste.model;

import java.io.Serializable;
import java.math.BigDecimal;
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.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.NotEmpty;

import br.com.teste.util.DecimalPositivo;

@Entity
@Table(name = "funcionario")
public class Funcionario implements Serializable {
    private static final long serialVersionUID = 1L;
    private Long id;

    private Pessoa pessoa;
    private String cpf;
    private String cargo;
    private BigDecimal salario;
    private TipoSexo sexo;
    private Date dataAdmissao;
    private Date dataDemissao;

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    //@NotNull
    @OneToOne
    @JoinColumn(name="pessoa_id")
    public Pessoa getPessoa() {
        return pessoa;
    }

    public void setPessoa(Pessoa pessoa) {
        this.pessoa = pessoa;
    }

    @NotEmpty
    @Size(max = 14)
    @Column(length = 14, nullable = false)
    public String getCpf() {
        return cpf;
    }

    public void setCpf(String cpf) {
        this.cpf = cpf;
    }

    @NotEmpty
    @Size(max = 80)
    @Column(length = 80, nullable = false)
    public String getCargo() {
        return cargo;
    }

    public void setCargo(String cargo) {
        this.cargo = cargo;
    }

    //@NotNull
    //@DecimalMin("0")
    @DecimalPositivo
    @Column(precision = 10, scale = 2, nullable = false)
    public BigDecimal getSalario() {
        return salario;
    }

    public void setSalario(BigDecimal salario) {
        this.salario = salario;
    }

    @NotNull
    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    public TipoSexo getSexo() {
        return sexo;
    }

    public void setSexo(TipoSexo sexo) {
        this.sexo = sexo;
    }

    @NotNull
    @Temporal(TemporalType.DATE)
    @Column(name = "data_admissao", nullable = false)
    public Date getDataAdmissao() {
        return dataAdmissao;
    }

    public void setDataAdmissao(Date dataAdmissao) {
        this.dataAdmissao = dataAdmissao;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "data_Demissao", nullable = true)
    public Date getDataDemissao() {
        return dataDemissao;
    }

    public void setDataDemissao(Date dataDemissao) {
        this.dataDemissao = dataDemissao;
    }


    @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;
        Funcionario other = (Funcionario) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }
}

My bean, CadastroFuncionarioBean.java:

package br.com.teste.model;

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

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
import javax.inject.Inject;
import javax.inject.Named;

import br.com.teste.controller.CadastroFuncionarios;
import br.com.teste.controller.CadastroPessoas;
import br.com.teste.controller.NegocioException;
import br.com.teste.repository.Funcionarios;
import br.com.teste.repository.Pessoas;

@Named
@javax.faces.view.ViewScoped
public class CadastroFuncionarioBean implements Serializable {
    private static final long serialVersionUID = 1L;

    @Inject
    private CadastroFuncionarios cadastrofuncionario;

    @Inject
    private CadastroPessoas cadastropessoa;

    @Inject
    private Pessoas pessoas;

    @Inject
    private Funcionarios funcionarios;

    private Funcionario funcionario;

    private Pessoa pessoa;

    private List<Pessoa> todasPessoas;

    private List<Funcionario> todosFuncionarios;

    public void prepararCadastro() {
        this.todasPessoas = this.pessoas.todas();
        if (this.pessoa == null) {
            this.pessoa = new Pessoa();
        }

        this.todosFuncionarios = this.funcionarios.todos();
        if (this.funcionario == null) {
            this.funcionario = new Funcionario();

        }
    }

    public void dataAdmissaoAlterada(AjaxBehaviorEvent event) {
        if (this.funcionario.getDataAdmissao() == null) {
            this.funcionario.setDataDemissao(this.funcionario.getDataAdmissao());
        }
    }

    public void salvar() {
        FacesContext context = FacesContext.getCurrentInstance();
        try {
            this.cadastropessoa.salvar(this.pessoa);
            this.pessoa = new Pessoa();
            this.cadastrofuncionario.salvar(this.funcionario);
            this.funcionario = new Funcionario();
            context.addMessage(null, new FacesMessage("Funcionario salvo com sucesso!"));
        } catch (NegocioException e) {
            FacesMessage mensagem = new FacesMessage(e.getMessage());
            mensagem.setSeverity(FacesMessage.SEVERITY_ERROR);
            context.addMessage(null, mensagem);
        }
    }

    public List<String> pesquisarCargos(String cargos) {
        return this.funcionarios.cargosQueContem(cargos);
    }

    public List<String> pesquisarCpfs(String cpfs) {
        return this.funcionarios.cpfsQueContem(cpfs);
    }

    public List<String> pesquisarNomes(String nomes) {
        return this.pessoas.nomesQueContem(nomes);
    }

    public List<String> pesquisarEnderecos(String enderecos) {
        return this.pessoas.enderecosQueContem(enderecos);
    }

    public List<String> pesquisarNumeros(String numeros) {
        return this.pessoas.numerosQueContem(numeros);
    }

    public List<String> pesquisarComplementos(String complementos) {
        return this.pessoas.complementosQueContem(complementos);
    }

    public List<String> pesquisarBairros(String bairros) {
        return this.pessoas.bairrosQueContem(bairros);
    }

    public List<String> pesquisarCidades(String cidades) {
        return this.pessoas.cidadesQueContem(cidades);
    }

    public List<String> pesquisarEstados(String estados) {
        return this.pessoas.estadosQueContem(estados);
    }

    public List<String> pesquisarCeps(String ceps) {
        return this.pessoas.cepsQueContem(ceps);
    }


    public List<Pessoa> getTodasPessoas() {
        return this.todasPessoas;
    }

    public List<Funcionario> getTodosFuncionarios() {
        return this.todosFuncionarios;
    }

    public TipoSexo[] getTiposFuncionarios() {
        return TipoSexo.values();
    }

    public Funcionario getFuncionario() {
        return funcionario;
    }

    public void setFuncionario(Funcionario funcionario) {
        this.funcionario = funcionario;
    }

    public Pessoa getPessoa() {
        return pessoa;
    }

    public void setPessoa(Pessoa pessoa) {
        this.pessoa = pessoa;
    }
}

My form = CadastroFuncionario.xhtml:

<!DOCTYPE html>
<ui:composition template="/WEB-INF/template/Layout.xhtml"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui">
    <f:metadata>
        <o:viewParam name="id" value="#{cadastroFuncionarioBean.funcionario}" />
        <f:viewAction action="#{cadastroFuncionarioBean.prepararCadastro}" />
    </f:metadata>
    <ui:define name="titulo">Cadastro RH</ui:define>
    <ui:define name="corpo">
        <h1>Cadastro de Funcionários</h1>
        <h:form id="frm">
            <p:messages showDetail="false" showSummary="true" autoUpdate="true" />

            <h3>Dados Pessoais</h3>
            <p:panelGrid columns="4">

                <p:outputLabel value="Nome" for="nome" />
                <p:autoComplete id="nome" size="60"
                    value="#{cadastroFuncionarioBean.pessoa.nome}"
                    completeMethod="#{cadastroFuncionarioBean.pesquisarNomes}" />

                    <p:outputLabel value="Cpf" for="cpf" />
                    <p:autoComplete id="cpf" size="14"
                        value="#{cadastroFuncionarioBean.funcionario.cpf}"
                        completeMethod="#{cadastroFuncionarioBean.pesquisarCpfs}" />

                    <p:outputLabel value="Tipo" for="sexo" />
                    <p:selectOneButton id="sexo"
                        value="#{cadastroFuncionarioBean.funcionario.sexo}">
                        <f:selectItems
                            value="#{cadastroFuncionarioBean.tiposFuncionarios}"
                            var="tipoFuncionario" itemValue="#{tipoFuncionario}"
                            itemLabel="#{tipoFuncionario.sexo}" />
                    </p:selectOneButton>

            </p:panelGrid>

            <h3>Endereço</h3>

            <p:panelGrid columns="4">

                <p:outputLabel value="Endereço" for="endereco" />
                <p:autoComplete id="endereco" size="60"
                    value="#{cadastroFuncionarioBean.pessoa.endereco}"
                    completeMethod="#{cadastroFuncionarioBean.pesquisarEnderecos}" />

                <p:outputLabel value="Numero" for="numero" />
                <p:autoComplete id="numero" size="6"
                    value="#{cadastroFuncionarioBean.pessoa.numero}"
                    completeMethod="#{cadastroFuncionarioBean.pesquisarNumeros}" />

                <p:outputLabel value="Complemento" for="complemento" />
                <p:autoComplete id="complemento" size="20"
                    value="#{cadastroFuncionarioBean.pessoa.complemento}"
                    completeMethod="#{cadastroFuncionarioBean.pesquisarComplementos}" />

                <p:outputLabel value="Bairro" for="bairro" />
                <p:autoComplete id="bairro" size="30"
                    value="#{cadastroFuncionarioBean.pessoa.bairro}"
                    completeMethod="#{cadastroFuncionarioBean.pesquisarBairros}" />

                <p:outputLabel value="Cidade" for="cidade" />
                <p:autoComplete id="cidade" size="30"
                    value="#{cadastroFuncionarioBean.pessoa.cidade}"
                    completeMethod="#{cadastroFuncionarioBean.pesquisarCidades}" />

                <p:outputLabel value="Estado" for="estado" />
                <p:autoComplete id="estado" size="2"
                    value="#{cadastroFuncionarioBean.pessoa.estado}"
                    completeMethod="#{cadastroFuncionarioBean.pesquisarEstados}" />

                <p:outputLabel value="Cep" for="cep" />
                <p:autoComplete id="cep" size="9"
                    value="#{cadastroFuncionarioBean.pessoa.cep}"
                    completeMethod="#{cadastroFuncionarioBean.pesquisarCeps}" />

            </p:panelGrid>

            <h3>Dados de Admissão</h3>

            <p:panelGrid columns="2">

                <p:outputLabel value="Cargo" for="cargo" />
                <p:autoComplete id="cargo" size="60"
                    value="#{cadastroFuncionarioBean.funcionario.cargo}"
                    completeMethod="#{cadastroFuncionarioBean.pesquisarCargos}" />

                <p:outputLabel value="Salário" />
                <p:inputText size="12"
                    value="#{cadastroFuncionarioBean.funcionario.salario}"
                    label="salario">
                    <f:convertNumber locale="pt_BR" maxFractionDigits="2"
                        minFractionDigits="2" />
                </p:inputText>

                <p:outputLabel value="Data de Admissão" for="dataAdmissao" />
                <p:calendar id="dataAdmissao" size="12" pattern="dd/MM/yyyy"
                    value="#{cadastroFuncionarioBean.funcionario.dataAdmissao}">
                    <p:ajax event="dateSelect" update="@this dataAdmissao"
                        process="@this dataAdmissao"
                        listener="#{cadastroFuncionarioBean.dataAdmissaoAlterada}" />
                </p:calendar>

            </p:panelGrid>

            <p:commandButton value="Salvar"
                action="#{cadastroFuncionarioBean.salvar}" icon="ui-icon-disk"
                update="@form" />

        </h:form>
    </ui:define>
</ui:composition>

If anyone can take a peek and tell me where I'm wrong, I'm grateful.

Answer:

Hello my suspicion about this error is the following, when you go to save the employee you do not set the person in it, so the person attribute in is null, as I understand you are filling the person variable with the form data, so it would be something as simple as in your Save method of CadastroPessoas return the saved person, jpa already returns a reference to the object managed by the JPA when the save method is called, and then it would just be to invoke the setPessoa in employee passing as parameter the return of the save method of CadastroPessoas , in code would look like this:

public void salvar() {
    FacesContext context = FacesContext.getCurrentInstance();
    try {
        Pessoa pessoaSalva = this.cadastropessoa.salvar(this.pessoa);
        this.funcionario.setPessoa(pessoaSalva);
        this.pessoa = new Pessoa();
        this.cadastrofuncionario.salvar(this.funcionario);
        this.funcionario = new Funcionario();
        context.addMessage(null, new FacesMessage("Funcionario salvo com sucesso!"));
    } catch (NegocioException e) {
        FacesMessage mensagem = new FacesMessage(e.getMessage());
        mensagem.setSeverity(FacesMessage.SEVERITY_ERROR);
        context.addMessage(null, mensagem);
    }
}
Scroll to Top
AllEscort