Hibernate 无法删除或更新父行:外键约束在联接表中失败
我正在使用Java8和Hibernate5/JPA2 尝试删除Hibernate 无法删除或更新父行:外键约束在联接表中失败,hibernate,jpa,Hibernate,Jpa,我正在使用Java8和Hibernate5/JPA2 尝试删除作业对象时,出现以下错误: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 无法删除或更新父行:外键约束失败 (wwwsubcategory,CONSTRAINTFK_subcategory_CATEGORY外键 (CATEGORY\u ID)在删除时参考CATEGORY(ID)在删除时不执行任何操作 更新(无操作) 表格 +===
作业
对象时,出现以下错误:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
无法删除或更新父行:外键约束失败
(www
subcategory
,CONSTRAINTFK_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)也应该删除子类别,而不仅仅是联接表中的记录。