2

I have a entity that has two Many-To-One relationships, and one of them cascades on save just fine and the other one returns:

Exception in thread "main" org.hibernate.TransientObjectException: object references an 
unsaved transient instance - save the transient instance before flushing : dto.publicSchema.Pessoas

Here is the code of the entity that works:

@Entity
@Table(name="`Doc_tipo`", schema="public")
public class Doc_tipo implements Serializable {

private static final long serialVersionUID = 1859372890916956036L;

@Id
@Column(nullable=false)
private int tp_doc;
@Column(nullable=false,columnDefinition="CHAR(255)")
private String descricao;
@Column(nullable=false,columnDefinition="CHAR(255)")
private String tp_emissor;

//getters and setters
}

And here is the code of the entity that will not allow cascade:

@Entity
@Table(name="`Pessoas`", schema="public")
public class Pessoas implements Serializable {

private static final long serialVersionUID = 8292302132119274975L;

@Id @GeneratedValue
@Column(nullable=false,columnDefinition="serial NOT NULL")
private int seq_pessoa;


static Date padrao_dt_criacao = new Date();
@Column(nullable=false, columnDefinition="date NOT NULL")
private Date dt_criacao = padrao_dt_criacao;

@Column(columnDefinition="CHAR(255)")
private String nome;

@Column(columnDefinition="CHAR(1) NULL")
private char tp_pessoa;

@Column(columnDefinition="CHAR(255)")
private String fantasia;

@Column(columnDefinition="VARCHAR(25)")
private String idioma;

@Column(columnDefinition="VARCHAR(25)")
private String login;

@Column(columnDefinition="VARCHAR(25)")
private String senha;   


static Date padrao_dt_i = new Date();
@Column(nullable=false, columnDefinition="date NOT NULL")
private Date dt_i = padrao_dt_i;

//Pessoa está ativa para o sitema se este campo estiver em branco
@Column(columnDefinition="date")
private Date dt_f; 

@Column(columnDefinition="oid")
private int foto;   

//getters and setters   
}   

And here is the class that has relationships Many-To-One with the two above but cascade will only work on the first one:

@Entity
@Table(name="`Documentos`", schema="public")
public class Documentos implements Serializable {

private static final long serialVersionUID = -4874330647877687810L;

@Id
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="seq_pessoa",columnDefinition="integer",referencedColumnName="seq_pessoa",nullable=false)
private Pessoas seq_pessoa;

@Id @GeneratedValue
@Column(nullable=false,columnDefinition="serial NOT NULL")
private int cd_doc;

@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="tp_doc",referencedColumnName="tp_doc",nullable=false)
private Doc_tipo tp_doc;

@Column(nullable=false)
private int tp_emissor;

@Column(nullable=false,columnDefinition="CHAR(2) NOT NULL DEFAULT 'DF'::bpchar")
private String tp_emissor_uf="DF";

@Column(columnDefinition="CHAR(5)")
private String alfa_doc;

@Column(nullable=false,columnDefinition="CHAR(20)")
private String nr_doc;

//Data de validade do documento
@Column(columnDefinition="date")
private Date dt_f_valid;

@Transient
transient static Date padrao_dt_i = new Date();
@Column(columnDefinition="date DEFAULT now()")
private Date dt_i = padrao_dt_i;

@Column(columnDefinition="date")
private Date dt_f;
    //getters and setters
}

When I go to save a Documentos object hibernate inserts the Doc_tipo in to its table as its supposed to, and instead of inserting the Pessoa object as well throws me that exception.

Here is the class that manipulates the session(it's just for tests):

public class Hibernate {



public static SessionFactory getSessionFactory() {

    SessionFactory sessionFactory = null;
    try {
        Configuration configuration = new Configuration();

        configuration.configure();

        ServiceRegistry  serviceRegistry = new  ServiceRegistryBuilder().applySettings(

        configuration.getProperties()).buildServiceRegistry();

        sessionFactory = configuration.buildSessionFactory(serviceRegistry);
    } catch (HibernateException hbe) {

        hbe.printStackTrace();

    }

    return sessionFactory;
}

public static void main(String[] args) {


    SessionFactory sessionFactory = getSessionFactory();
    Session session = sessionFactory.openSession();
    session.beginTransaction();


    Pessoas a = new Pessoas();
    a.setDt_criacao(new Date());
    a.setDt_f(new Date());
    a.setDt_i(new Date());
    a.setFantasia("teste");
    a.setFoto(12);
    a.setIdioma("aa");
    a.setLogin("aa");
    a.setNome("aa");
    a.setSenha("a");
    a.setTp_pessoa('H');



    Doc_tipo b = new Doc_tipo();
    b.setDescricao("aa");
    b.setTp_doc(5);
    b.setTp_emissor("aaa");


    Documentos c = new Documentos();

    c.setAlfa_doc("aaa");
    c.setDt_f(new Date());
    c.setDt_f_valid(new Date());
    c.setDt_i(new Date());
    c.setNr_doc("aa");
    c.setSeq_pessoa(a);
    c.setTp_doc(b);
    c.setTp_emissor(1);
    c.setTp_emissor_uf("aa");

    //session.save(a);
    session.save(c);





    session.getTransaction().commit();
    session.close();



}

}

If i remove the comment on the save() Pessoas object, everything works fine, but i shouldn't have to do that, the same exception happens when i try to cascade save in another entity that has a Many-To-One relationship with Pessoas too.

4

1 回答 1

0

Documentos 使用主键 (Pessoas.seq_pessoa) 引用 Pessoas,该主键仅在保存/刷新到数据库后创建,因为 Pessoas 使用串行。所以在保存/持久实际发生之前没有什么可参考的。

此外,您不应使用多个 @Id 注释来定义复合标识,除非您还定义了包含上述 @Id 字段的 @IdClass。或者你也可以 @EmbeddedId 注释。JPA 支持两种不同的复合 PK 方法。在每种情况下,都必须有一个包含这些字段的 PK 类。

A) 实体上的多个@Id 字段/属性。实体中字段的名称和类型必须与 PK 类中的字段匹配。类上还必须有 @IdClass 注释。前任:

public class EmpPK {
int id;
String name;
...
}

@Entity
@IdClass(EmpPK.class)
public class Employee {
@Id int id;
@Id String name;

...
}

B) 在实体中嵌入 PK 类的属性。在这种情况下,属性用@EmbeddedId 标记,PK 类必须用@Embeddable 注释。前任:

@Embeddable
public class EmpPK {
int id;
String name;
...
}

@Entity
public class Employee {
@EmbeddedId EmpPK empId;
...
}
于 2013-09-10T11:15:19.093 回答