java - 使用hibernate删除mysql中的行: Cannot delete or update a parent row

标签 java hibernate

我有两个类,Fount 和 Criterions,第一个是一对多,另一个是多对一。当我调用删除时,我收到标题中提到的错误。

我在 stackoverflow 和其他网站上尝试了很多关于同一问题的解决方案,但我做不到,如果有人发现我会很高兴

我尝试过的解决方案:

Cascade - as you can see, i'm already using the annotation, and i tried a lot of different annotations that i found in the internet

Remove the object Criterion from the object Fount and then the Fount from the Criterion before deleting the Criterion from the database

Remove from Fount object and updating the database right after it

错误:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (mydb.fount_criterion, CONSTRAINT FK5p3wsropwaokyta6cmy3edvcv FOREIGN KEY (criterions_id) REFERENCES criterion (id))

我的类(class)字体和标准:

package br.com.engcon.entities;

import javax.persistence.*;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "fount")
//@SequenceGenerator(name="SEQUENCE", sequenceName="fount_id_seq")
public class Fount {
    
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id; 
    
    @Column(nullable=false, name="url")
    private String url;
    
    @OneToMany(fetch = FetchType.LAZY, targetEntity = Criterion.class)
    @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE})
    private List<Criterion> criterions;
//  
//  @OneToMany(fetch = FetchType.LAZY, targetEntity = Text.class, orphanRemoval = true)
//  @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE})
//  private List<Text> texts;

    @Column(nullable=false, name="isUsed")
    private boolean isUsed = false;

    @Column(nullable=false, name="isActive")
    private boolean isActive = true;
    
    @Column(nullable=false, name="isDeleted")
    private boolean isDeleted = false;

    public Fount(String url) throws URISyntaxException {
        this.url = url;
        this.criterions = new ArrayList<Criterion>();

        new URI(url);
    }
    
    public Fount(String url, List<Criterion> criterions) {
        this.url = url;
        this.criterions = criterions != null? criterions : new ArrayList<Criterion>();
    }
    
    public Fount() {
        this.criterions = new ArrayList<Criterion>();
    }
    
    public URI getURI() {
        if(!url.isEmpty()) {
            try {
                return new URI(url);
            } catch (URISyntaxException e) {
                return null;
            }
        }
        return null;
    }
    
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public List<Criterion> getCriterions() {
        return criterions;
    }

    public void setCriterions(List<Criterion> criterions) {
        this.criterions = criterions;
    }

    public void setUrl(String url) {
        this.url = url;
    }
    
    public void addCriterions(List<Criterion> criterions){
        this.criterions = this.criterions != null? this.criterions : new ArrayList<Criterion>();
        
        this.criterions.addAll(criterions);
    }
    
    public void addCriterions(Fount fount) {
        this.criterions = criterions != null? criterions : new ArrayList<Criterion>();
        
        for(Criterion criterion : fount.getCriterions()) {
            Criterion newCriterion = criterion.clone();
            
            newCriterion.setFount(this);
            
            criterions.add(newCriterion);
        }
    }

    public Criterion addCriterion(Criterion criterion) {
        this.criterions = criterions != null? criterions : new ArrayList<Criterion>();

        Criterion newCriterion = criterion.clone();
        newCriterion.setFount(this);
        
        this.criterions.add(newCriterion);

        return criterion;
    }

    public Criterion addCriterion(String criterionTxt) {
        return this.addCriterion(new Criterion(criterionTxt));
    }
    
    public String getUrl() {
        return this.url;
    }
    
    @Override
    public String toString() {
        return this.getUrl();
    }

    public boolean isUsed() {
        return isUsed;
    }

    public void setUsed(boolean used) {
        isUsed = used;
    }

    public boolean isActive() {
        return isActive;
    }

    public void setActive(boolean active) {
        isActive = active;
    }

    public boolean isDeleted() {
        return isDeleted;
    }

    public void setDeleted(boolean isDeleted) {
        this.isDeleted = isDeleted;
    }
}

标准:

package br.com.engcon.entities;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

@Entity
@Table(name = "criterion")
//@SequenceGenerator(name="SEQUENCE", sequenceName="criterion_id_seq")
public class Criterion {
        
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @ManyToOne(fetch=FetchType.EAGER)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @JoinColumn(name="fount_id", nullable=false)
    private Fount fount;
    
    @Column(nullable=true, name="word_filter")
    private String word;
    
    @Column(nullable=false, name="case_sensitive")
    private boolean caseSensitive;
    
    public Criterion() {
        // TODO Auto-generated constructor stub
        caseSensitive = false;
    }
    
    public Criterion(String word) {
        this.word = word;
        this.caseSensitive = false;
    }
    
    public Criterion(String word, boolean caseSensitive) {
        this.word = word;
        this.caseSensitive = caseSensitive;
    }
    
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getWord() {
        return word;
    }
    
    @Override
    public Criterion clone(){
        return new Criterion(this.word, this.caseSensitive);
    }
    
    public void setWord(String word) {
        this.word = word;
    }

    public boolean isCaseSensitive() {
        return caseSensitive;
    }

    public void setCaseSensitive(boolean caseSensitive) {
        this.caseSensitive = caseSensitive;
    }

    public Fount getFount() {
        return fount;
    }

    public void setFount(Fount fount) {
        this.fount = fount;
    }
    
    @Override
    public String toString() {
        return this.word;
    }
}

最佳答案

您需要synchronize both end of the bidirectional association .

如果您只有 1 个双向关联(在您的示例中 - Criterion-Fount 和 Fount-Criterion),则以下辅助方法(用于解除父实体与所有子实体的关联)将解决该问题:

public void addCriterion(Criterion criterion) {
    criterions.add(comment);
    criterion.setFount(this);
}

public void removeCriterion(Criterion criterion) {
    criterions.remove(criterion);
    criterion.setFount(null);
}

并确保您使用级联:

@OneToMany(mappedBy = "fount", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Criterion> criterions;

关于java - 使用hibernate删除mysql中的行: Cannot delete or update a parent row,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52634492/

相关文章:

java - 有没有一种优雅的方式在 Springs @Query 注释中使用枚举?

java - Android 通过各种 Activity 使 BT 套接字保持 Activity 状态

java - Java中链式方法回调会导致堆栈溢出吗?

java - 斯坦福 NER 重新训练的内存要求

java - Spring 和 Hibernate c3p0 错误无法完成架构验证

java - 按父对象设置的子对象的值对父对象进行排序

java - Hibernate createNativeQuery 使用 IN 子句

java - 使用 xStream 序列化 BiMap

java - 在网页中使用分页真的有任何性能优势吗?

java - hibernate中的查询枚举抛出DataException : Bad value for type int : t