After much research, without success, I decided to post my doubts.
I'm using JPA / Hibernate and I have two tables: a Pessoa
and a Funcionário
.
The error occurs when I save my data, the foreign key pessoa_id
is empty, that is, null
.
I will post my code below in the hope 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 = official.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, AffiliateBean.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 = AffiliateFax.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 someone can take a look and tell me where I'm wrong I'm grateful.