【发布时间】:2019-07-12 08:53:53
【问题描述】:
我有两张普通表和一张关系表。
--------------------------------------------------
| Group | Membership | User |
| (ID, NAME) |(GRP_ID, U_ID) |(ID, FORENAME) |
--------------------------------------------------
| 1, Admin | 1, 1 | 1, Joe |
--------------------------------------------------
会员有两个外键
FK1 Membership.GRP_ID -> Group.ID
FK2 Membership.U_ID -> User.ID
我可以将cascade-delete 设置为每个外键(FK1 和FK2)。
事实 1
如果 FK1 和 FK2 都没有删除级联,我既不能删除 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 没有级联删除,则可以删除管理员(删除成员资格)但不能删除乔。
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(删除成员资格)但不能删除管理员。
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 将删除成员资格,但 Admin 保持不变。删除 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) 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 只允许一个删除级联?
【问题讨论】:
-
你能用示例代码解释一下吗?使用了哪个级联?
-
@MostafaMashayekhi 当然,你喜欢什么语言和数据库?
-
这很清楚,因为你使用了java和spring标签
-
@PeterRader 没关系,我试图提供帮助,但您的出色态度令人讨厌。体验与 Stackoverflow 的使用不成正比。祝你好运。
-
@Villat 你说得对,这是一种理想主义的态度,很抱歉偷了你的时间。我更改了问题以添加理想主义标签。
标签: java hibernate many-to-many cascading-deletes