java - hibernate : Not allowing cascaded delete because of Foreign key violations

标签 java spring hibernate postgresql spring-mvc

我正在开发一个 Spring-MVC 应用程序,我试图在其中删除一个实体,该实体与其他 3 个实体具有一对多关系。我已在 Cascade 上标记要删除的实体,但它不起作用。我收到外键违规错误..

注释实体:

@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 检索列表并在 for 循环中删除,这也没有用。我不明白如何解决这个问题。非常感谢。

最佳答案

这里有几处错误。首先,调用 clear() 只处理双向关系的一侧。您需要访问每个 child 并将其对 GroupNote 的引用设置为 null。按照你写的方式,刷新后数据库将保持不变,不会删除任何实体。

其次,在 HQL 中调用 delete 会绕过 cascade 选项。因此,即使没有第一个问题,也不会以这种方式删除任何相关实体,从而导致您看到的异常。

关于java - hibernate : Not allowing cascaded delete because of Foreign key violations,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30167794/

相关文章:

java - 我需要一种更好的方法来减少代码行,其中有很多 if 语句和条件调用方法

java - 如何将时间戳转换为几天前

java - 如何配置 java jackson 不在空 bean 上抛出 NPE 异常?

java - 用于提取字符串的正则表达式从 '=' 开始,到 '\t' 结束

java - Spring Integration Aggregator - 丢失消息

spring - 如果未经身份验证请求uri,如何让spring安全响应未经授权(http 401代码)

java - Hibernate 急切地加载惰性引用

java - Hibernate 查询在字符串字段中搜索特定子字符串

java - Spring Data JPA 中的 FetchMode 是如何工作的

java - 防止 Spring Boot 注册 Spring Security 过滤器之一