CascadeType.ALL 没有 CascadeType.REMOVE 更改持续行为
CascadeType.ALL without CascadeType.REMOVE changes persist behavior
在这个项目中,我有两个实体 A 和 B,每个实体都与实体 C 具有 OneToOne 关系。A 和 B 引用了一些 C。
@Entity
public class A {
@NotNull
@OneToOne(cascade = { CascadeType.ALL })
@JoinColumn(name = "fk_c", foreignKey = @ForeignKey(name = "fk_a_2_c"))
private C c;
}
@Entity
public class B {
@NotNull
@OneToOne(cascade = { CascadeType.ALL })
@JoinColumn(name = "fk_c", foreignKey = @ForeignKey(name = "fk_b_2_c"))
private C c;
}
@Entity
public class C {
@Nullable
@OneToOne(mappedBy = "c", fetch = FetchType.LAZY)
private A a;
@Nullable
@OneToOne(mappedBy = "c", fetch = FetchType.LAZY)
private B b;
}
直到现在,在实体 B 中的字段 c 上使用 CascadeType.ALL 一切正常。我们现在想要删除实体 B,而不删除实体 C。因此,我们将实体 B 中的级联更改为
@OneToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
现在,删除行为符合要求,但是当持久化实体 B 时,实体 C 没有持久化级联,而是我们得到一个 org.springframework.dao.InvalidDataAccessApiUsageException
Not-null property references a transient value - transient instance must be saved before current operation : xxx.B.c -> xxx.C
我已经尝试放置所有级联类型(PERSIST、MERGE、REMOVE、REFRESH、DETACH),根据 javax.persistence 文档,它们应该产生与 CascadeType.ALL 相同的结果。仍然出现上述错误。
那么:如何在没有 REMOVE 级联的情况下保持 CascadeType.ALL 的级联行为?
在较旧的 question/answer 中,我了解到 javax.persistence 的 CascadeType 枚举在使用休眠时无法正常工作 save/saveOrUpdate。
使用 session.persist 而不是 session.saveOrUpdate 在我的情况下是不可取的,所以我需要从
更改实体上的级联
@OneToOne(cascade = CascadeType.ALL)
到
@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
@OneToOne
现在保存和删除都可以正常工作了。
在这个项目中,我有两个实体 A 和 B,每个实体都与实体 C 具有 OneToOne 关系。A 和 B 引用了一些 C。
@Entity
public class A {
@NotNull
@OneToOne(cascade = { CascadeType.ALL })
@JoinColumn(name = "fk_c", foreignKey = @ForeignKey(name = "fk_a_2_c"))
private C c;
}
@Entity
public class B {
@NotNull
@OneToOne(cascade = { CascadeType.ALL })
@JoinColumn(name = "fk_c", foreignKey = @ForeignKey(name = "fk_b_2_c"))
private C c;
}
@Entity
public class C {
@Nullable
@OneToOne(mappedBy = "c", fetch = FetchType.LAZY)
private A a;
@Nullable
@OneToOne(mappedBy = "c", fetch = FetchType.LAZY)
private B b;
}
直到现在,在实体 B 中的字段 c 上使用 CascadeType.ALL 一切正常。我们现在想要删除实体 B,而不删除实体 C。因此,我们将实体 B 中的级联更改为
@OneToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
现在,删除行为符合要求,但是当持久化实体 B 时,实体 C 没有持久化级联,而是我们得到一个 org.springframework.dao.InvalidDataAccessApiUsageException
Not-null property references a transient value - transient instance must be saved before current operation : xxx.B.c -> xxx.C
我已经尝试放置所有级联类型(PERSIST、MERGE、REMOVE、REFRESH、DETACH),根据 javax.persistence 文档,它们应该产生与 CascadeType.ALL 相同的结果。仍然出现上述错误。
那么:如何在没有 REMOVE 级联的情况下保持 CascadeType.ALL 的级联行为?
在较旧的 question/answer
使用 session.persist 而不是 session.saveOrUpdate 在我的情况下是不可取的,所以我需要从
更改实体上的级联@OneToOne(cascade = CascadeType.ALL)
到
@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
@OneToOne
现在保存和删除都可以正常工作了。