如何在不删除实际目标实体的情况下删除@ManyToMany 关联(加入link)
How to delete a @ManyToMany association (joined link) without deleting the actual target entity
我正在开发一个 Spring-MVC 应用程序,其中包含多对多映射。有3张表,一张是GroupAccount,memberjunction,GroupMembers。现在,当我删除一个 groupMember 时,我只想删除 GroupMembers 和 memberId 对应的 memberjunction 中的条目。我尝试使用 Cascade.Remove,它也导致了 GroupAccount 中的删除。我正在发布我的 sql 代码,以及我目前拥有的代码。
SQL代码:
CREATE TABLE groupaccount
(
groupid numeric NOT NULL,
groupname character varying,
adminusername character varying,
CONSTRAINT groupid PRIMARY KEY (groupid)
)
CREATE TABLE memberjunction
(
memberid integer NOT NULL,
groupid numeric NOT NULL,
CONSTRAINT membergroupid PRIMARY KEY (memberid, groupid),
CONSTRAINT groupaccount_memberjunction_fk FOREIGN KEY (groupid)
REFERENCES groupaccount (groupid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT groupmembers_memberjunction_fk FOREIGN KEY (memberid)
REFERENCES groupmembers (memberid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
CREATE TABLE groupmembers
(
memberid integer NOT NULL,
musername character varying,
accesslevel boolean DEFAULT true,
CONSTRAINT memberid PRIMARY KEY (memberid)
)
GroupMembersDAOImpl删除方法:
@Override
public boolean removeGroupMember(int memberId) {
session = sessionFactory.getCurrentSession();
GroupMembers groupMembers = (GroupMembers) session.get(GroupMembers.class, memberId);
if(!(groupMembers == null)){
groupMembers.getGroupAccounts().clear();
session.flush();
session.delete(groupMembers);
return true;
} else {
return false;
}
}
GroupAccount 实体:
@Entity
@Table(name="groupaccount")
public class GroupAccount {
@Id
@Column(name="groupid")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "groupaccount_seq_gen")
@SequenceGenerator(name = "groupaccount_seq_gen",sequenceName = "groupaccount_seq")
private Long groupId;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "memberjunction", joinColumns = {@JoinColumn(name = "groupid")},
inverseJoinColumns = {@JoinColumn(name = "memberid")})
private Set<GroupMembers> groupMembersSet = new HashSet<>();
public void setGroupMembersSet(Set<GroupMembers> groupMembersSet){
this.groupMembersSet = groupMembersSet;
}
public Set<GroupMembers> getGroupMembersSet(){
return this.groupMembersSet;
}
}
群组成员实体:
@Entity
@Table(name="groupmembers")
public class GroupMembers {
@Id
@Column(name="memberid")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "groupmembers_seq_gen")
@SequenceGenerator(name = "groupmembers_seq_gen",sequenceName = "groupmembers_seq")
private int memberid;
@ManyToMany(mappedBy = "groupMembersSet")
private Set<GroupAccount> groupAccounts = new HashSet<>();
public void setGroupAccounts(Set<GroupAccount> groupAccounts){
this.groupAccounts = groupAccounts;
}
public Set<GroupAccount> getGroupAccounts(){
return this.groupAccounts;
}
}
最新错误日志:
org.postgresql.util.PSQLException: ERROR: update or delete on table "groupmembers" violates foreign key constraint "groupmembers_memberjunction_fk" on table "memberjunction"
Detail: Key (memberid)=(2501) is still referenced from table "memberjunction".
org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1927)
上述方法无效,如其所说,存在对memberJunction 的引用。我如何查询 memberJunction 并删除与 memberId 对应的条目。你能帮忙的话,我会很高兴。非常感谢..:-)
您需要执行以下操作:
for(GroupAccount groupAccount : groupMembers.getGroupAccounts()) {
groupAccount.getGroupMembersSet().remove(this);
}
groupMembers.getGroupAccounts().clear();
session.flush();
session.delete(groupMembers);
因为您有一个 @ManyToMany
关联,关联 table 在运行时不可用。为此,您可以:
在删除群组成员之前从 GroupMembers
中清除 GroupAccounts
。确保刷新,以便确保删除操作 doesn't prevent 是针对删除 table 实体状态的更新。
您可以将 @ManyToMany
替换为与 MemberJunction
实体的 @OneToMany
关联(其 PK/@Id 是从 GroupMembers
和 GroupAccount
)。通过这种方式,您可以将删除从 GroupMembers
级联到 MemberJunction
mappedBy
集合,因为它将删除关联 table 行,而不是实际的 GroupAccount
实体.
我正在开发一个 Spring-MVC 应用程序,其中包含多对多映射。有3张表,一张是GroupAccount,memberjunction,GroupMembers。现在,当我删除一个 groupMember 时,我只想删除 GroupMembers 和 memberId 对应的 memberjunction 中的条目。我尝试使用 Cascade.Remove,它也导致了 GroupAccount 中的删除。我正在发布我的 sql 代码,以及我目前拥有的代码。
SQL代码:
CREATE TABLE groupaccount
(
groupid numeric NOT NULL,
groupname character varying,
adminusername character varying,
CONSTRAINT groupid PRIMARY KEY (groupid)
)
CREATE TABLE memberjunction
(
memberid integer NOT NULL,
groupid numeric NOT NULL,
CONSTRAINT membergroupid PRIMARY KEY (memberid, groupid),
CONSTRAINT groupaccount_memberjunction_fk FOREIGN KEY (groupid)
REFERENCES groupaccount (groupid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT groupmembers_memberjunction_fk FOREIGN KEY (memberid)
REFERENCES groupmembers (memberid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
CREATE TABLE groupmembers
(
memberid integer NOT NULL,
musername character varying,
accesslevel boolean DEFAULT true,
CONSTRAINT memberid PRIMARY KEY (memberid)
)
GroupMembersDAOImpl删除方法:
@Override
public boolean removeGroupMember(int memberId) {
session = sessionFactory.getCurrentSession();
GroupMembers groupMembers = (GroupMembers) session.get(GroupMembers.class, memberId);
if(!(groupMembers == null)){
groupMembers.getGroupAccounts().clear();
session.flush();
session.delete(groupMembers);
return true;
} else {
return false;
}
}
GroupAccount 实体:
@Entity
@Table(name="groupaccount")
public class GroupAccount {
@Id
@Column(name="groupid")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "groupaccount_seq_gen")
@SequenceGenerator(name = "groupaccount_seq_gen",sequenceName = "groupaccount_seq")
private Long groupId;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "memberjunction", joinColumns = {@JoinColumn(name = "groupid")},
inverseJoinColumns = {@JoinColumn(name = "memberid")})
private Set<GroupMembers> groupMembersSet = new HashSet<>();
public void setGroupMembersSet(Set<GroupMembers> groupMembersSet){
this.groupMembersSet = groupMembersSet;
}
public Set<GroupMembers> getGroupMembersSet(){
return this.groupMembersSet;
}
}
群组成员实体:
@Entity
@Table(name="groupmembers")
public class GroupMembers {
@Id
@Column(name="memberid")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "groupmembers_seq_gen")
@SequenceGenerator(name = "groupmembers_seq_gen",sequenceName = "groupmembers_seq")
private int memberid;
@ManyToMany(mappedBy = "groupMembersSet")
private Set<GroupAccount> groupAccounts = new HashSet<>();
public void setGroupAccounts(Set<GroupAccount> groupAccounts){
this.groupAccounts = groupAccounts;
}
public Set<GroupAccount> getGroupAccounts(){
return this.groupAccounts;
}
}
最新错误日志:
org.postgresql.util.PSQLException: ERROR: update or delete on table "groupmembers" violates foreign key constraint "groupmembers_memberjunction_fk" on table "memberjunction"
Detail: Key (memberid)=(2501) is still referenced from table "memberjunction".
org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1927)
上述方法无效,如其所说,存在对memberJunction 的引用。我如何查询 memberJunction 并删除与 memberId 对应的条目。你能帮忙的话,我会很高兴。非常感谢..:-)
您需要执行以下操作:
for(GroupAccount groupAccount : groupMembers.getGroupAccounts()) {
groupAccount.getGroupMembersSet().remove(this);
}
groupMembers.getGroupAccounts().clear();
session.flush();
session.delete(groupMembers);
因为您有一个 @ManyToMany
关联,关联 table 在运行时不可用。为此,您可以:
在删除群组成员之前从
GroupMembers
中清除GroupAccounts
。确保刷新,以便确保删除操作 doesn't prevent 是针对删除 table 实体状态的更新。您可以将
@ManyToMany
替换为与MemberJunction
实体的@OneToMany
关联(其 PK/@Id 是从GroupMembers
和GroupAccount
)。通过这种方式,您可以将删除从GroupMembers
级联到MemberJunction
mappedBy
集合,因为它将删除关联 table 行,而不是实际的GroupAccount
实体.