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

  • 本文关键字:实体 JPA 操作 级联 标识 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
}

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

然后我试着persist()家长:

this.em.persist(parent);

。并且我在 Informix 数据库中收到外键冲突。 另一方面,我们的 H2 数据库可以很好地处理这个问题。

这是应该发生的事情吗? 我做错了什么吗?

我有一些问题可能会对您有所帮助。请在您的原始帖子中回答他们:

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

Q2:NULLABLE旗呢?(两个数据库)

Q3:调试并检查调用 persist() 时子项中 parentId 的 ID 是什么。

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

希望回答其中一个问题能给你解决问题的方法。

最新更新