使用休眠模式在mysql中删除行:无法删除或更新父行

时间:2018-10-03 19:37:30

标签: java hibernate

我有两个班级,分别是Fount和Criterions,第一个是一对多的,另一个是一对一的。当我致电Delete时,出现标题中提到的错误。

我在stackoverflow和其他站点上针对相同问题尝试了很多解决方案,但是我做得不好,如果有人发现我会很高兴

我尝试过的解决方案:

  

层叠-如您所见,我已经在使用注释,并且尝试了很多在互联网上找到的注释

     

先从对象Fount中删除对象Criterion,然后再从Criterion中删除Fount,然后再从数据库中删除Criterion

     

从Fount对象中删除并紧随其后更新数据库

错误:

  

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:   无法删除或更新父行:外键约束失败   ({mydbfount_criterion,约束   FK5p3wsropwaokyta6cmy3edvcv外键(criterions_id)参考   criterionid))

我的班级“标准与准则”:

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;
    }
}

1 个答案:

答案 0 :(得分:1)

您需要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;