当父项具有生成的标识时,如何将JPA持久操作级联到子实体?

时间:2013-09-20 19:02:41

标签: jpa

我在父实体和子实体之间存在双向@OneToOne关系。

在父母身上,我有这个(是的,孩子是这段关系的拥有者):

@OneToOne(mappedBy = "parent", fetch = FetchType.EAGER, optional = true, cascade = { CascadeType.ALL })
private Child child;

他的主键是(遗憾地)由数据库生成:

@Column(name = "id", updatable = false)
@GeneratedValue(GenerationType.IDENTITY)
@Id
private long id;

在孩子身上,我有这个:

// note: insertable = false, updatable = false
@JoinColumn(name = "parentId", referencedColumnName = "id", insertable = false, updatable = false)
@OneToOne(optional = false, fetch = FetchType.EAGER, cascade = { CascadeType.REFRESH })
private Parent parent;

@Column(name = "parentId", updatable = false)
@Id
private long parentId;

通常我会使用@PrimaryKeyJoinColumn注释而不是这两个映射,但是有几个JPA提供程序在这方面存在错误。

在某些时候,我在一个新的父实例上做了一些工作。作为这项工作的一部分,我这样做:

this.child = new Child(this);

...并在Child(Parent)构造函数内部执行此操作:

this.parent = parent; // now the bidirectionality is complete
if (parent != null) {
  this.parentId = parent.getId(); // suspect; will be 0L
}

所以,如果你和我在一起,到目前为止,我有一个由ParentChild组成的对象图,这些对象彼此之间有@OneToOne个关系,并已正确初始化。这两个对象都是非托管实体。

然后我尝试persist()父母:

this.em.persist(parent);

...我在Informix数据库中遇到外键违规。另一方面,我们的H2数据库处理得很好。

应该发生什么?我做错了吗?

1 个答案:

答案 0 :(得分:0)

我有一些问题可能对您有所帮助。请在原帖中回答:

Q1:你确定你有一把外键吗? H2数据库中的主键约束(检查)?

Q2:NULLABLE旗帜怎么样? (两个数据库)

问题3:调用并检查调用persist()时孩子中parentId的ID是什么。

问题4:是否可以从父项中删除CascadeType.ALL并手动管理(或仅保留)操作?

希望回答其中一个问题将为您解决问题。