Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 无法删除或更新父行:外键约束在联接表中失败_Hibernate_Jpa - Fatal编程技术网

Hibernate 无法删除或更新父行:外键约束在联接表中失败

Hibernate 无法删除或更新父行:外键约束在联接表中失败,hibernate,jpa,Hibernate,Jpa,我正在使用Java8和Hibernate5/JPA2 尝试删除作业对象时,出现以下错误: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 无法删除或更新父行:外键约束失败 (wwwsubcategory,CONSTRAINTFK_subcategory_CATEGORY外键 (CATEGORY\u ID)在删除时参考CATEGORY(ID)在删除时不执行任何操作 更新(无操作) 表格 +===

我正在使用Java8和Hibernate5/JPA2

尝试删除
作业
对象时,出现以下错误:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 无法删除或更新父行:外键约束失败 (
www
subcategory
,CONSTRAINT
FK_subcategory_CATEGORY
外键 (
CATEGORY\u ID
)在删除时参考
CATEGORY
ID
)在删除时不执行任何操作 更新(无操作)

表格

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

                 +==================+   +=================+
                 | job_subcategory  |   | subcategory     |   
                 +==================+   +=================+
                 |  JOB_ID          |   |  ID             |
                 |  SUBCAT_ID       |   |  CATEGORY_ID    |
                 +==================+   +=================+
一个
作业
可以有许多
类别
。一个
类别
可以有许多
子类别

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;
@JsonIgnore
@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER, mappedBy = "category")
private Set<SubCategory> subCategories;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name = "CATEGORY_ID")
private Category category;
protected void remove(Job entity) {
    entityManager.remove(entity);
}
JpaDao.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;
@JsonIgnore
@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER, mappedBy = "category")
private Set<SubCategory> subCategories;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name = "CATEGORY_ID")
private Category category;
protected void remove(Job entity) {
    entityManager.remove(entity);
}
当我删除
Job
对象时,我希望它从
Job
表和联接表(
Job\u category
Job\u子类别
)中删除一行,而不是从
category
子类别
表中删除一行

谢谢你的建议

更新

我尝试删除
子类别
类别
,然后删除
作业

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;
}
但请再次获得以下信息:

无法删除或更新父行:外键约束失败 (
www
person\u job
,约束
fk\u person\u job\u person
外键 (
PER_ID
)在删除时参考
person
ID
)在更新时不执行任何操作 (行动)

更新

我尝试:

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

IllegalArgumentException:源不能为null


这是典型的SQL错误。即使使用纯SQL,如果您试图在单个查询中删除依赖行和父行,您也会遇到此错误

首先,删除(取消链接)关系(从
作业
中删除
类别
子类别
),然后删除
作业
这是在您的更新中完成的


您还必须将
人员
工作
中删除;)还有你在这里没有提到的工作的所有其他关系。

好吧,试试这样的事情

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;
}
公共布尔删除(作业){
Set subCategories=job.getSubCategories();
if(子类别!=null){
job.getSubCategories().clear();
用于(子类别子类别:子类别){
子类别.setJob(空);
entityManager.remove(子类别);
}
}
Set categories=job.getCategories();
如果(类别!=null){
job.getCategories().clear();
用于(类别:类别){
category.setJob(空);
entityManager.remove(类别);
}
}
job.setPerson(空);
//如有需要:
//Person.setJob(null);
entityManager.remove(作业);
返回true;
}
还有,为什么像我刚才发布的代码一样,你有
super.remove(job)
而没有
entityManager.remove(job)


此代码是否仍有异常?

删除与作业关联的第一个类别和子类别。然后删除作业(当然全部在一个事务中)。谢谢John,我试过了,但还是出错了。请参阅我已在上面进行了更新。在删除子类别之前,请尝试从作业的子类别中删除(这里不是em.remove())对作业的引用(将其设置为null),并从作业中删除对子类别的引用(清空该集)。删除(em.remove())子类别。对作业的类别也要这样做。现在删除作业。好吧,现在是另一个例外。数据库中还有一个人,你可能也需要以同样的方式删除“个人工作”链接(你没有显示相关的数据库部分),在这种情况下,你已经对类别和子类别进行了删除。谢谢,我现在没有注意到它是“个人”。如果我这样做,它会不会从类别和子类别表中删除?我只想从连接表中删除。这很有效,谢谢John。我已将此标记为答案。它不会从类别和子类别表中删除。仅按预期删除联接表。谢谢“它不会从类别和子类别表中删除。只会按预期删除联接表。”-好的,很高兴您的代码正常工作。但您使用的代码可能与我发布的代码不完全相同,因为entityManager.remove(subCategory)也应该删除子类别,而不仅仅是联接表中的记录。