- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有两个普通表和一个关系表。
--------------------------------------------------
| 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
我可以为每个外键(FK1
和 FK2
)设置 cascade-delete
。
如果 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)
);
如果 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)
);
如果 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
);
如果FK2
级联删除和FK
1级联删除。删除 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/
我写了这个课: class StaticList { private: int headFree; int headList; int locNe
我目前正在使用 SQL Server Management Studio 2005,我遇到了一些问题,但首先是我的 DB 架构的摘录(重要的): imghack link to the image 我
范围:两个表。创建新顾客时,他们会将一些有关他们的信息存储到第二个表中(这也是使用触发器完成的,它按预期工作)。这是我的表结构和关系的示例。 表 1-> 赞助人 +-----+---------+--
我想知道,在整个程序中,我使用了很多指向 cstrings 的 char* 指针,以及其他指针。我想确保在程序完成后删除所有指针,即使 Visual Studio 和 Code Blocks 都为我做
考虑以下代码: class Foo { Monster* monsters[6]; Foo() { for (int i = 0; i < 6; i++)
关于 this page , 是这么写的 One reason is that the operand of delete need not be an lvalue. Consider: delet
我无法在 DELETE CASCADE ON UPDATE CASCADE 上添加外键约束。 我使用两个简单的表格。 TAB1 有 2 列:ID int(10) unsigned NOT NULL A
你好,有没有办法把它放在一个声明中? DELETE e_worklist where wbs_element = '00000000000000000054TTO'. DELETE e_workli
我有一个表,它是我系统的核心,向我的客户显示的所有结果都存储在那里。它增长得非常快,因此每 3 小时我应该删除早于 X 的记录以提高性能。 仅删除这些记录就足够了,还是应该在删除后运行优化表? 我正在
这个问题在这里已经有了答案: delete vs delete[] operators in C++ (7 个答案) 关闭 9 年前。 做和做有什么区别: int* I = new int[100]
为什么这段代码是错误的?我是否遗漏了有关 delete 和 delete[] 行为的内容? void remove_stopwords(char** strings, int* length) {
当我使用 new [] 申请内存时。最后,我使用 delete 来释放内存(不是 delete[])。会不会造成内存泄漏? 两种类型: 内置类型,如 int、char、double ... 我不确定。
所以在代码审查期间,我的一位同事使用了 double* d = new double[foo]; 然后调用了 delete d。我告诉他们应该将其更改为 delete [] d。他们说编译器不需要基本
范围:两个表。当一个新顾客被创建时,他们将一些关于他们的信息存储到第二个表中(这也是使用触发器完成的,它按预期工作)。这是我的表结构和关系的示例。 表 1-> 赞助人 +-----+---------
C++14 介绍 "sized" versions of operator delete ,即 void operator delete( void* ptr, std::size_t sz ); 和
我正在执行类似的语句 DELETE FROM USER WHERE USER_ID=1; 在 SQLDeveloper 中。 由于用户在许多表中被引用(例如用户有订单、设置等),我们激活了 ON DE
出于某种原因,我找不到我需要的确切答案。我在这里搜索了最后 20 分钟。 我知道这很简单。很简单。但由于某种原因我无法触发触发器.. 我有一个包含两列的表格 dbo.HashTags |__Id_|_
这是我的代码: #include #include #include int main() { setvbuf(stdout, NULL, _IONBF, 0); setvbuf
是否可以在 postgres 中使用单个命令删除所有表中的所有行(不破坏数据库),或者在 postgres 中级联删除? 如果没有,那么我该如何重置我的测试数据库? 最佳答案 is it possib
我想删除一些临时文件的内容,所以我正在开发一个小程序来帮我删除它们。我有这两个代码示例,但我对以下内容感到困惑: 哪个代码示例更好? 第一个示例 code1 删除文件 1 和 2,但第二个示例 cod
我是一名优秀的程序员,十分优秀!