Object references an unsaved transient instance (Erro ao salvar)

Gostaria de uma ajuda, ainda não consegui resolver esse problema.

@Entity
@Table(schema="public", name="aluno")
@SequenceGenerator(name="id_creator", sequenceName="aluno_id")
public class Aluno implements java.io.Serializable {

	private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO, generator="id_creator")
    @Column(name="id_aluno")
    private Long id;

	@OneToOne
    @JoinColumn(name="id_escola")
    private Escola escola = new Escola();

    @OneToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="id_endereco")
    private Endereco endereco = new Endereco();

    @OneToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="id_contato")
    private Contato contato = new Contato();

    @OneToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="id_responsavel")
    private AlunoResponsavel responsavel = new AlunoResponsavel();

    @Column(name="nome", nullable=false, length=50)
    private String nome;

    @Column(name="cpf", unique=true, nullable=false, length=14)
    private String cpf;

    @Column(name="rg", nullable=false, length=12)
    private String rg;

    @Column(name="comentario", length=255)
    private String comentario;

    @Column(name="data_nascimento", nullable=false)
    @Temporal(TemporalType.DATE)
    private Date dataNascimento;

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

    @Column(name="excluido")
    private Short excluido;

    @OneToOne
    @JoinColumn(name="id_funcionario_exclusao")
    private Funcionario funcionarioExclusao;
}

Classe AlunoResponsavel

@Entity
@Table(schema="public", name="aluno_responsavel")
@SequenceGenerator(name="id_creator", sequenceName="aluno_responsavel_id")
public class AlunoResponsavel implements java.io.Serializable {

	private static final long serialVersionUID = 2L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO, generator="id_creator")
    @Column(name="id_responsavel")
    private Long id;
    
	@OneToOne
    @JoinColumn(name="id_escola")
    private Escola escola = new Escola();

    @OneToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="id_endereco")
    private Endereco endereco = new Endereco();

    @OneToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="id_contato")
    private Contato contato = new Contato();

    @Column(name="nome", nullable=false, length=50)
    private String nome;

    @Column(name="cpf", unique=true, nullable=false, length=14)
    private String cpf;

    @Column(name="rg", nullable=false, length=12)
    private String rg;

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

    @Column(name="excluido")
    private Short excluido;

    @OneToOne
    @JoinColumn(name="id_funcionario_exclusao")
    private Funcionario funcionarioExclusao;

}

Classe Contato

@Entity
@Table(schema="public", name="contato")
@SequenceGenerator(name="id_creator", sequenceName="contato_id")
public class Contato implements java.io.Serializable {

	private static final long serialVersionUID = 3L;

	@Id
    @GeneratedValue(strategy=GenerationType.AUTO, generator="id_creator")
    @Column(name="id_contato")
    private Long id;

    @Column(name="email", unique=true, nullable=false, length=50)
    private String email;

    @Column(name="telefone", nullable=false, length=13)
    private String telefone;

    @Column(name="celular", length=14)
    private String celular;

}

Classe Endereco

@Entity
@Table(schema="public", name="endereco")
@SequenceGenerator(name="id_creator", sequenceName="endereco_id")
public class Endereco implements java.io.Serializable {

	private static final long serialVersionUID = 5L;

	@Id
    @GeneratedValue(strategy=GenerationType.AUTO, generator="id_creator")
    @Column(name="id_endereco")
    private Long id;

    @Column(name="logradouro", nullable=false, length=50)
    private String logradouro;

    @Column(name="numero", nullable=false, length=5)
    private String numero;

    @Column(name="bairro", nullable=false, length=50)
    private String bairro;

    @Column(name="cidade", nullable=false, length=50)
    private String cidade;

    @Column(name="estado", nullable=false, length=2)
    private String estado;
    
    @Column(name="complemento", length=255)
    private String complemento;

    @Column(name="cep", length=9)
    private String cep;
}

Classe Escola

@Entity
@Table(schema="public", name="escola")
@SequenceGenerator(name="id_creator", sequenceName="escola_id")
public class Escola implements java.io.Serializable {

	private static final long serialVersionUID = 6L;

	@Id
    @GeneratedValue(strategy=GenerationType.AUTO, generator="id_creator")
    @Column(name="id_escola")
    private Long id;

    @OneToOne
    @JoinColumn(name="id_endereco")
    private Endereco endereco;

    @OneToOne
    @JoinColumn(name="id_contato")
    private Contato contato;

    @Column(name="razao_social", nullable=false, length=100)
    private String razaoSocial;

    @Column(name="nome_fantasia", nullable=false, length=100)
    private String nomeFantasia;

    @Column(name="cnpj", unique=true, nullable=false)
    private String cnpj;
}

Classe AlunoDAO

public void save(T t) throws DAOException {
	try {
		HibernateHelper.getManagedSession().save(t);
	} catch (Exception e) {
		throw new DAOException(e);
	}
}

Classe HibernateHelper

public static Session getManagedSession() {
	return getManagedSession(true);
}

private static Session getManagedSession(boolean forceTransaction) {
	Session s = sessionFactory.getCurrentSession();
	if (forceTransaction && !s.getTransaction().isActive()) {
		s.beginTransaction();
	}
	return s;
}

public static Transaction getTransaction() {
	return getManagedSession(false).getTransaction();
}

O commit é dado via Filtro:

Transaction tx = HibernateHelper.getTransaction();
if (tx.isActive()) {
	if (tudoOk){
		tx.commit();
	}else{
		tx.rollback();
	}
}

e causa o erro:

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: br.com.renaissance.entities.Escola
	at org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:249)
	at org.hibernate.type.EntityType.getIdentifier(EntityType.java:459)

No caso em questão, não quero persistir a Escola, a mesma é preenchida de acordo com o user logado na aplicação.

Desde já agradeço.

Coloca o código que gera o erro.

Se não quer persistir o objeto escola então tem que anular ele na hora de salvar.

Opa,

Editei o post e coloquei o trecho do Filtro, se possível dá uma nova analisada.

Muito obrigado.

Onde vc passa essa Escola que já vem preenchida para o objeto que vc quer salvar?

Sim, eu seto o valor no controller

getAluno().setEscola(JsfUtil.getEscolaFuncionarioLogged());

Boas, realizando novos testes, o erro é causado pela entidade AlunoResponsavel, o atributo escola não está nulo, mas não está setado conforme acima.

Na verdade isso não faz sentido,pois ele quer associar uma escola ao objeto em questão,só não quer persistir o objeto escola em si.

[quote=robinsonbsilva]Sim, eu seto o valor no controller

getAluno().setEscola(JsfUtil.getEscolaFuncionarioLogged());

Boas, realizando novos testes, o erro é causado pela entidade AlunoResponsavel, o atributo escola não está nulo, mas não está setado conforme acima.[/quote]

Deixa eu ver esse metodo JsfUtil.getEscolaFuncionarioLogged()

Boas raf4ever,

Está dando certo agora, o problema se dá quando o AlunoResponsavel não é informado, como se trata de uma informação opcional.
Ai o que ocorria, na omissão do Responsavel, o atributo Escola fica diferente de null, mas sem um ID de chave estrangeira válido.

Obrigadão!!

salve o objeto que será settado antes de settar.


public class pessoa {

     private Endereco endereco;

}

public class Endereco {

     private Pessoa pessoa;

}


public class Controller {

   // salve o objeto settado antes. esse objeto ainda não existe no banco (não tem id), logo não tem como se gerada uma fk pra ele
     dao.save(pessoa);
     endereco.setEndereco(pessoa);
    dao.save(endereco);

}