gpt4 book ai didi

java - 关系表 delete-cascade 在 4 种情况下,但 Entity-config 只允许 2

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:26:22 26 4
gpt4 key购买 nike

我有两个普通表和一个关系表。

 --------------------------------------------------
| Group | Membership | User |
| (ID, NAME) |(GRP_ID, U_ID) |(ID, FORENAME) |
--------------------------------------------------
| 1, Admin | 1, 1 | 1, Joe |
--------------------------------------------------

成员(member)有两个外键

FK1 Membership.GRP_ID -> Group.ID
FK2 Membership.U_ID -> User.ID

我可以为每个外键(FK1FK2)设置 cascade-delete


事实 1

如果 FK1FK2 都没有删除级联,我就不能删除 Admin 和 Joe,因为他们在“成员身份”中保持连接。

CREATE TABLE Membership (
GRP_ID INT NOT NULL,
U_ID INT NOT NULL,
FOREIGN KEY (GRP_ID) REFERENCES Group (id),
FOREIGN KEY (U_ID) REFERENCES User (id)
);

事实 2

如果 FK1 级联删除但 FK2 没有,您可以删除 Admin(删除成员资格)但不能删除 Joe。

CREATE TABLE Membership (
GRP_ID INT NOT NULL,
U_ID INT NOT NULL,
FOREIGN KEY (GRP_ID) REFERENCES Group (id) ON DELETE CASCADE,
FOREIGN KEY (U_ID) REFERENCES User (id)
);

事实 3

如果 FK2 级联删除但 FK1 没有,您可以删除 Joe(删除成员的内容)但不能删除 Admin。

CREATE TABLE Membership (
GRP_ID INT NOT NULL,
U_ID INT NOT NULL,
FOREIGN KEY (GRP_ID) REFERENCES Group (id),
FOREIGN KEY (U_ID) REFERENCES User (id) ON DELETE CASCADE
);

事实 4

如果FK2级联删除FK1级联删除。删除 Joe 将删除 Membership,但 Admin 保持不变。删除 Admin 将删除 Membership,但 Joe 保持不变。

CREATE TABLE Membership (
GRP_ID INT NOT NULL,
U_ID INT NOT NULL,
FOREIGN KEY (GRP_ID) REFERENCES Group (id) ON DELETE CASCADE,
FOREIGN KEY (U_ID) REFERENCES User (id) ON DELETE CASCADE
);


组Java代码:

// @formatter:off
import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.io.Serializable;
import javax.persistence.ManyToOne;
import javax.persistence.JoinColumn;
import javax.persistence.Column;
import javax.persistence.Version;
import javax.persistence.SequenceGenerator;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import org.hibernate.envers.Audited;
import java.util.LinkedHashSet;
import javax.persistence.OneToMany;
import java.util.Set;
import javax.persistence.OrderBy;
import javax.persistence.ManyToMany;
import javax.persistence.JoinTable;

@Entity
@Table(name="Group")
@SuppressWarnings("serial")
public class Group implements java.io.Serializable {
private Integer id;
private Set<User> users = new LinkedHashSet<>();
private String name;

@Id
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "gen241738")
@SequenceGenerator(name = "gen241738", sequenceName = "seq_group_id")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}

@OrderBy
@ManyToMany
@JoinTable(name="Membership", joinColumns = {
@JoinColumn(name="GRP_ID", referencedColumnName="ID", nullable=false),
}, inverseJoinColumns = {
@JoinColumn(name="U_ID", referencedColumnName="ID", nullable=false)
})
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}

@Column(name = "NAME", nullable = false)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
//@formatter:on


问题

当关系表包含两个外键时,将可能性扩展到 2x2=4 情况,为什么注释 @ManyToMany只允许一个删除级联?

最佳答案

When a relationtable contains two foreign keys scaling the possibilitys to 2x2=4 cases, why does the annotation @ManyToMany allows only one delete-cascadation?

级联不仅由类型定义,而且由 relationship 的拥有方定义。 :

Entities that use relationships often have dependencies on the existence of the other entity in the relationship. For example, a line item is part of an order; if the order is deleted, the line item also should be deleted. This is called a cascade delete relationship.

对于 @ManyToMany :

Every many-to-many association has two sides, the owning side and the non-owning, or inverse, side. The join table is specified on the owning side. If the association is bidirectional, either side may be designated as the owning side. If the relationship is bidirectional, the non-owning side must use the mappedBy element of the ManyToMany annotation to specify the relationship field or property of the owning side. The join table for the relationship, if not defaulted, is specified on the owning side.

因此,从您的示例来看,Group 是拥有方,我认为 User 是非拥有方,因此它代表事实 2事实 3 反之亦然。

@Entity
@Table(name="Group")
@SuppressWarnings("serial")
public class Group implements java.io.Serializable {

@OrderBy
@ManyToMany
@JoinTable(name="Membership", joinColumns = {
@JoinColumn(name="GRP_ID", referencedColumnName="ID", nullable=false),
}, inverseJoinColumns = {
@JoinColumn(name="U_ID", referencedColumnName="ID", nullable=false)
})
public Set<User> getUsers() {
return users;
}
}

如果关联是双向的,则任何一方都可以指定为拥有方。如果这样做,您将代表您的事实 4

对于最后一个示例,您应该将 Mapping 表的 POJO 表示定义为每个关系的拥有方。

我向您展示了没有遗漏的配置/字段,并且所有情况都可以通过指定拥有方来完成。您错误地期望 @ManyToMany 的字段 cascade 进行整个级联配置。


刚刚在评论中发现您实际上是在寻求对级联的解释:

The answer did not help me in understanding what is the matter of cascade=null

使用cascade,您可以指定必须级联到关联目标的操作。级联是由 hibernate 执行的,它不是数据库级别的级联操作。通过上面定义的关系,我们判断与 Group 关联的 User 是否也应该在 Group 执行时保留/合并/删除/刷新/分离(使用适当的类型)或不使用(using cascade=null)。

关于java - 关系表 delete-cascade 在 4 种情况下,但 Entity-config 只允许 2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57003509/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com