无法删除或更新父行:外键约束因连接表而失败

时间:2016-09-26 10:29:24

标签: hibernate jpa

我正在使用Java 8和Hibernate5 / JPA2。

当我尝试删除Job对象时出现以下错误:

  

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:   无法删除或更新父行:外键约束失败   (wwwsubcategory,CONSTRAINT FK_SUBCATEGORY_CATEGORY FOREIGN KEY   (CATEGORY_ID)引用categoryID)ON DELETE NO ACTION ON   更新无行动)

+============+   +=================+   +================+
| job        |   |  job_category   |   |  category      |
+============+   +=================+   +================+
| ID         |   |  JOB_ID         |   |  ID            |
|            |   |  CAT_ID         |   |                |
+============+   +=================+   +================+

                 +==================+   +=================+
                 | job_subcategory  |   | subcategory     |   
                 +==================+   +=================+
                 |  JOB_ID          |   |  ID             |
                 |  SUBCAT_ID       |   |  CATEGORY_ID    |
                 +==================+   +=================+

Job可以有多个CategoriesCategory可以包含多个SubCategories

Job.java

@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "job_category", joinColumns = {
        @JoinColumn(name = "JOB_ID", referencedColumnName = "ID") }, inverseJoinColumns = {
                @JoinColumn(name = "CAT_ID", referencedColumnName = "ID") })
private Set<Category> categories;

@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "job_subcategory", joinColumns = {
        @JoinColumn(name = "JOB_ID", referencedColumnName = "ID") }, inverseJoinColumns = {
                @JoinColumn(name = "SUBCAT_ID", referencedColumnName = "ID") })
private Set<SubCategory> subCategories;

Category.java

@JsonIgnore
@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER, mappedBy = "category")
private Set<SubCategory> subCategories;

SubCategory.java

@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name = "CATEGORY_ID")
private Category category;

JpaDao.java

protected void remove(Job entity) {
    entityManager.remove(entity);
}

当我删除Job对象时,我希望它从job表和连接表(job_categoryjob_subcategory)中删除一行,但不是categorysubcategory表。

任何建议都表示赞赏。

更新

我尝试删除subcategoriescategories,然后删除job

public boolean delete(Job job) {
    Set<SubCategory> subCategories = job.getSubCategories();
    if (subCategories != null) {
        for (SubCategory subCategory : subCategories) {
            entityManager.remove(subCategory);
        }
    }
    Set<Category> categories = job.getCategories();
    if (categories != null) {
        for (Category category : categories) {
            entityManager.remove(category);
        }
    }
    entityManager.remove(job);
    return true;
}

但我仍然得到同样的错误:

  

无法删除或更新父行:外键约束失败   (wwwjob_subcategory,CONSTRAINT fk_job_sub_subcategory外国   KEY(SUBCAT_ID)引用subcategoryID)ON DELETE NO ACTION   ON UPDATE NO ACTION)

只有当我完成事务(@Transactional)时才会出现错误,所以它看起来就像Hibernate执行提交时一样。

更新

我尝试以下方法:

public boolean delete(Job job) {
    job.setSubCategories(null);
    job.setCategories(null);
    super.remove(job);
    return true;
}

但是再次获得以下内容:

  

无法删除或更新父行:外键约束失败   (wwwperson_job,CONSTRAINT fk_person_job_person FOREIGN KEY   (PER_ID)引用personID)删除没有更新的操作否   ACTION)

更新

我试试:

public boolean delete(Job job) {
    job.setSubCategories(null); 
    job.setCategories(null);
    job.setPerson(null);        
    super.remove(job);
    return true;
}

并获得:

  

IllegalArgumentException:Source不能为null

2 个答案:

答案 0 :(得分:1)

好吧,尝试类似的东西

public boolean delete(Job job) {
    Set<SubCategory> subCategories = job.getSubCategories();
    if (subCategories != null) {
        job.getSubCategories().clear();
        for (SubCategory subCategory : subCategories) {
            subCategory.setJob(null);
            entityManager.remove(subCategory);
        }
    }
    Set<Category> categories = job.getCategories();
    if (categories != null) {
        job.getCategories().clear();
        for (Category category : categories) {
            category.setJob(null);
            entityManager.remove(category);
        }
    }
    job.setPerson(null);
    //if necessary:
    //Person.setJob(null);        
    entityManager.remove(job);
    return true;
}

另外,为什么你有super.remove(job)而不是entityManager.remove(job),就像我刚发布的代码一样?

您是否仍然使用此代码获得异常?

答案 1 :(得分:0)

这是典型的SQL错误。即使使用纯SQL,如果您尝试在单个查询中删除相关行和父项,yo也会收到此错误。

首先,删除(取消关联)关系(从category删除subcategoriesjob),然后删除job。 - 这是在您的更新中完成的。

您还必须从person删除job;以及此处未提及的job所有其他关系。