我正在研究一个Spring-MVC应用程序,在该应用程序中,我正在尝试删除与其他3个实体有一对一关系的实体。我已经标记了要在级联上删除的实体,但它不起作用。我遇到了违反外国密钥的错误。
注意实体:
@Entity
@Table(name="groupnotes")
public class GroupNotes {
@OneToMany(mappedBy = "mnotedata",fetch = FetchType.EAGER,cascade = CascadeType.REMOVE)
private Set<GroupAttachments> mattachments = new HashSet<>();
public Set<GroupAttachments> getMattachments() {
return this.mattachments;
}
public void setMattachments(Set<GroupAttachments> mattachments) {
this.mattachments = mattachments;
}
@OneToMany(mappedBy = "mhistory",fetch = FetchType.LAZY,cascade = CascadeType.REMOVE)
private Set<GroupNoteHistory> groupNoteHistorySet = new HashSet<>();
public Set<GroupNoteHistory> getGroupNoteHistorySet(){
return this.groupNoteHistorySet;
}
public void setGroupNoteHistorySet(Set<GroupNoteHistory> groupNoteHistorySet){
this.groupNoteHistorySet = groupNoteHistorySet;
}
@OneToMany(mappedBy = "unreadNotes",fetch = FetchType.LAZY,cascade = CascadeType.REMOVE)
private Set<UnreadNotes> unreadNotesSet = new HashSet<>();
public Set<UnreadNotes> getUnreadNotesSet(){
return this.unreadNotesSet;
}
public void setUnreadNotesSet(Set<UnreadNotes> unreadNotesSet){
this.unreadNotesSet = unreadNotesSet;
}
}
实体集群:
@Entity
@Table(name = "groupattachments")
public class GroupAttachments {
@ManyToOne
@JoinColumn(name = "mnoteid")
@OnDelete(action = org.hibernate.annotations.OnDeleteAction.CASCADE)
private GroupNotes mnotedata;
public void setMnotedata(GroupNotes mnotedata){this.mnotedata=mnotedata;}
public GroupNotes getMnotedata(){return mnotedata;}
}
但是,当我执行以下代码时:
@Override
public boolean deleteAllNotesForSection(int msectionid) {
session = this.sessionFactory.getCurrentSession();
org.hibernate.Query query = session.createQuery("from GroupNotes as " +
"n where n.ownednotes.msectionid=:msectionid");
query.setParameter("msectionid",msectionid);
List<GroupNotes> groupNotesList = query.list();
for(GroupNotes groupNotes : groupNotesList){
groupNotes.getGroupNoteHistorySet().clear();
groupNotes.getMattachments().clear();
groupNotes.getUnreadNotesSet().clear();
session.flush();
}
org.hibernate.Query query1 = session.createQuery("delete from GroupNotes as " +
"n where n.ownednotes.msectionid=:msectionid");
query1.setParameter("msectionid",msectionid);
query1.executeUpdate();
session.flush();
return true;
}
执行上述代码时会出现以下错误:
SEVERE: Servlet.service() for servlet [appServlet] in context with path [] threw exception [Request processing failed; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
org.postgresql.util.PSQLException: ERROR: update or delete on table "groupnotes" violates foreign key constraint "groupnotes_groupnotehistory_fk" on table "groupnotehistory"
Detail: Key (mnoteid)=(5455) is still referenced from table "groupnotehistory".
不是清除所有集合的第一个查询,应该从数据库中清除历史记录和所有内容。理想情况下,应该没有问题,因为它是级联删除。我还尝试使用query1.list和删除的前面删除来检索列表,但也无效。我不明白如何解决这个问题。非常感谢。
这里有几件事是错误的。首先,调用clear()
仅处理双向关系的一侧。您需要访问每个孩子,并将其引用到 GroupNote
到null。您写的方式,数据库将在冲洗后保持不变,不会删除任何实体。
第二,在HQL旁路中调用delete
cascade
选项。因此,即使没有第一个问题,也不会以这种方式删除相关实体,从而导致您看到的例外。