Search code examples
javahibernatejpahibernate-mapping

Not-null property references a transient value Hibernate


I have two tables with relationships 1 : n

Many to one employees and department an employee can only have one department.

One to many and a department has several employees.

The departments table already has the departments created a new department need not be created to add an employee (only one that exists)

My model: Funcionario / many to one

@Entity(name="Funcionario")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "tipo", length = 1, discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("F")
@Table(name = "funconarios")
public abstract class Funcionario implements Autenticar {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "codFuncionario")
    private String codFuncionario;

    @ManyToOne  
    @JoinColumn(name="codDepart", referencedColumnName="codDepart",nullable=false)  
    private Departamento departamento;

    //private Endereco endereco;
    @Column(name = "matricula")
    private String matricula;
    @Column(name = "nome")
    private String nome;
    @Column(name = "cpf")
    private String cpf;
    @Column(name = "rg")
    private String rg;
    @Column(name = "usuario")
    private String usuario;
    @Column(name = "senha")
    private String senha;
    @Column(name = "dataEntrada")
    private Date dataEntrada; 
    @Column(name = "dataSaida")
    private Date dataSaida;
    @Column(name = "dataNascimento")
    private Date dataNascimento;
    @Column(name = "salario")
    private Double salario;

//construtores  
    public Funcionario() {
    }

my model DEPARTAMENT / one to many:

@Entity
@Table(name="departamento") 
public class Departamento {
    @Id  
    @GeneratedValue  
    @Column(name="codDepart") 
    private Integer codDepartamento;
    @Column(name="nome")  
    private String nomeDepartamento;

    @OneToMany(mappedBy="departamento", cascade= CascadeType.ALL)  
    private Set<Funcionario> funcionarios;  

    public Departamento() {
    }

    public Integer getCodDepartamento() {
        return codDepartamento;
    }

    public void setCodDepartamento(Integer codDepartamento) {
        this.codDepartamento = codDepartamento;
    }

    public String getNomeDepartamento() {
        return nomeDepartamento;
    }

    public void setNomeDepartamento(String nomeDepartamento) {
        this.nomeDepartamento = nomeDepartamento;
    }

    @Override
    public String toString() {
        return "Departamento [codDepartamento=" + codDepartamento + ", nomeDepartamento=" + nomeDepartamento
                + ", funcionarios=" + funcionarios + "]";
    }



}

my method save:

public void save(T entity) {
    getSession().saveOrUpdate(entity);
}

my main:

public static void main(String[] args) {
    Departamento depart = new Departamento();
    Funcionario funcionario = new Vendedor();
    funcionario.setNome("Maria");
    funcionario.setCpf("11111111111");
    funcionario.setRg("2222222222");
    funcionario.setMatricula("124");
    funcionario.setDataNascimento(java.sql.Date.valueOf("2005-02-01"));
    funcionario.setDataEntrada(java.sql.Date.valueOf("2005-02-01"));
    funcionario.setSalario(987.00);
    funcionario.setUsuario("xd");
    funcionario.setSenha("xd");
    Departamento departamento = new Departamento();
    departamento.setNomeDepartamento("teste");
    funcionario.setDepartamento(departamento);

    GenericDAO absx = new DepartamentoDAO(Funcionario.class);
    absx.beginTransaction();
    absx.save(funcionario);
    absx.commit();

}

my erros stacktrace:

WARN: HHH000437: Attempting to save one or more entities that have a non-nullable association with an unsaved transient entity. 
The unsaved transient entity must be saved in an operation prior to saving these dependent entities.  
Unsaved transient entity: ([model.Departamento#<null>])   Dependent entities: ([[model.Vendedor#<null>]])     
Non-nullable association(s): ([model.Vendedor.departamento]) Exception in thread "main"
org.hibernate.TransientPropertyValueException: Not-null property
references a transient value - transient instance must be saved before
current operation : model.Vendedor.departamento -> model.Departamento

at org.hibernate.action.internal.UnresolvedEntityInsertActions.checkNoUnresolvedActionsAfterOperation(UnresolvedEntityInsertActions.java:122)

at org.hibernate.engine.spi.ActionQueue.checkNoUnresolvedActionsAfterOperation(ActionQueue.java:436)

at org.hibernate.internal.SessionImpl.checkNoUnresolvedActionsAfterOperation(SessionImpl.java:651)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:683)

at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:673)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:668)

at dao.GenericDAO.save(GenericDAO.java:54)
at view.eeee.main(eeee.java:35)

Solution

  • You have to cascade the change. Place in your Funcionario class:

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="codDepart", referencedColumnName="codDepart",nullable=false)  
    private Departamento departamento;