2 つの多対 1 の関係を持つエンティティがあり、そのうちの 1 つは保存時にカスケードされ、もう 1 つは返されます。
Exception in thread "main" org.hibernate.TransientObjectException: object references an
unsaved transient instance - save the transient instance before flushing : dto.publicSchema.Pessoas
動作するエンティティのコードは次のとおりです。
@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
}
カスケードを許可しないエンティティのコードは次のとおりです。
@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
}
上記の 2 つと多対 1 の関係を持つクラスを次に示しますが、カスケードは最初の 1 つに対してのみ機能します。
@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
}
Documentos オブジェクトを保存しようとすると、休止状態で Doc_tipo が想定どおりにテーブルに挿入され、Pessoa オブジェクトを挿入する代わりに、その例外がスローされます。
セッションを操作するクラスは次のとおりです (テスト用です)。
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();
}
}
save() Pessoas オブジェクトのコメントを削除すると、すべて正常に動作しますが、そうする必要はありません。多対 1 の関係を持つ別のエンティティで保存をカスケードしようとすると、同じ例外が発生します。ペソアも。