且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

有关JPA级联和删除实体的问题

更新时间:2023-02-02 23:20:10

您的问题本身就是错误的,这是所有混乱的根源. Arthur的回答做得很好,但是从评论中可以明显看出,混乱仍然存在,所以让我在这里a一口.

Your question is wrong in and of itself, which is where all the confusion stems from. Arthur did a good job with his answer but it's clear from the comments the the confusion still remains so let me take a stab at it here.

仅当我指定时,级联才成立 他们在拥有 关系吗?

Do cascades hold only when I specify them on the entity owning the relationship?

级联"是您在关系的一端(或者在双向情况下可能同时在两端)上指定的属性.它确定在上执行的动作将被传播到 other 端.有许多不同的类型在JPA和

"cascade" is an attribute you specify on one (or possibly both in case of bi-directional) end of a relationship. It determines what actions performed on that end will be propagated to the other end. There are many different types of those actions defined in JPA and even more defined in Hibernate extensions. This distinction is important - you should only talk about specific behavior being propagated and not "cascade" in general.

PERSIST,MERGE和REFRESH正常传播(从声明它们的一端到另一个).

PERSIST, MERGE, REFRESH propagate normally (from the end they were declared on to the other).

但是,REMOVE是棘手的,因为它可能意味着两种不同的含义.如果您在 A B 之间建立了联系,并尝试删除 A ,则可以删除 B 在另一端,或者您可以删除关联,但保留 B 不变. Hibernate明确区分了两者-您可以分别声明REMOVE(DELETE)和DELETE_ORPHAN级联类型; JPA规范没有.请注意,单值关系(OneToOne/ManyToOne)不支持DELETE_ORPHAN.

REMOVE, however, is tricky because it can mean two different things. If you have a relationship between A and B and you're trying to remove A, you can either remove B on the other end OR you can remove the association but leave B intact. Hibernate makes a clear distinction between the two - you can declare REMOVE (DELETE) and DELETE_ORPHAN cascade types separately; JPA spec does not. Note that DELETE_ORPHAN is not supported to single-valued relationships (OneToOne / ManyToOne).

因此,REMOVE的传播(本身或作为ALL的一部分)取决于关系是否具有明确的所有者(单向总是这样做;双向使用如果使用 mappedBy 进行映射,则双向这样做).如果是通过 join table 映射的,则不这样做),在这种情况下,它是从所有者传播到拥有者的,或者没有所有者,在这种情况下,它是沿任一方向传播的,但是没有DELETE_ORPHAN语义,除非明确指定.后者的典型示例是双向多对多.

Thus, propagation of REMOVE (by itself or when it's part of ALL) depends on whether relationship has a clear owner (uni-directional always does; bi-directional does if it's mapped using mappedBy and does not if it's mapped via join table) in which case it's propagated from owner to owned OR no owner in which case it's propagated in either direction but without DELETE_ORPHAN semantics unless it was explicitly specified. Typical example of the latter is bi-directional many-to-many.