且构网

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

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

更新时间:2023-02-02 23:07:42

你的问题本身就是错误的,这就是所有混乱的根源.亚瑟的回答做得很好,但从评论中可以清楚地看出,混乱仍然存在,所以让我在这里试一试.

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?

级联"是您在关系的一端(或在双向的情况下可能是两者)指定的属性.它决定在那个端执行的动作将传播到另一端.有 许多不同的类型 定义在 JPA 和 甚至更多在 Hibernate 扩展中定义.这种区别很重要 - 您应该只讨论正在传播的特定行为,而不是一般的级联".

"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 很棘手,因为它可能意味着两个不同的东西.如果您有 AB 之间的关系,并且您要删除 A,则可以删除 B> 在另一端,或者您可以删除 关联,但保持 B 不变.Hibernate 明确区分了两者——您可以分别声明 REMOVE (DELETE) 和 DELETE_ORPHAN 级联类型;JPA 规范没有.请注意,DELETE_ORPHAN 不支持单值关系(OneToOne/ManyToOne).

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 的一部分时)取决于关系是否有明确的所有者(单向总是如此;如果使用 ma​​ppedBy 和如果它通过连接表映射,则不会,在这种情况下,它从所有者传播到拥有者或没有所有者,在这种情况下,它在任一方向传播但没有 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.