英文:
Why I got a DataIntegrityViolationException even using CascadeType.ALL?
问题
我有一张表格,有以下这些关系:
parent
| \
child1 child1
/ \
grandchild1 grandchild2
我之所以称之为孙子、子女和父母,只是为了说明问题... 这不是继承问题
Parent.java
@Entity
@Table(name = "parent")
@Data
@EqualsAndHashCode(callSuper = true, exclude = { "..." })
@ToString(exclude = { "..." })
@NoArgsConstructor
public class Parent {
private static final long serialVersionUID = 1L;
@OneToMany(mappedBy = "parent")
@Cascade({org.hibernate.annotations.CascadeType.ALL})
private Set<Child> children;
}
Child.java
@Entity
@Table(name = "child")
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class Child {
private static final long serialVersionUID = 1L;
@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;
@OneToMany(mappedBy = "child")
@Cascade({org.hibernate.annotations.CascadeType.ALL})
@LazyCollection(LazyCollectionOption.FALSE)
private List<Grandchild> grandchildren = new ArrayList<>();
}
我尝试直接删除一个父项,使用CascadeType.ALL我看不到任何问题。但当我尝试删除时,出现了以下错误:
> 08-26 11:36:33,755 ERROR [SqlExceptionHelper] 无法删除或更新父行:外键约束失败 (database
.child
,CONSTRAINT FK_abcdefg12345
FOREIGN KEY (parent_id
) REFERENCES parent_id
(id
)) 2020-08-26 11:36:33,773 INFO [AbstractBatchImpl ] HHH000010:批处理释放时仍包含 JDBC 语句 26-Aug-2020 11:36:33.776 WARNING [http-nio-8080-exec-6] com.sun.faces.lifecycle.InvokeApplicationPhase.execute #{delete()}:org.springframework.dao.DataIntegrityViolationException:无法执行语句;SQL [n/a];约束[null];嵌套异常是 org.hibernate.exception.ConstraintViolationException:无法执行语句
我认为可能是从 JPA 导入了错误的 CascadeType,而不是从 org.hibernate 导入。我还尝试只使用 JPA 代码,例如 @OneToMany(mappedBy = "parent", orphanRemoval = true, cascade = CascadeType.ALL),但不起作用。
代码
parent.setChildren(null);
parentRepository.delete(parent); //抛出异常
依赖项
- Spring Data JPA 1.7.0
- Hibernate 4.2.1.Final
- Spring Integration JDBC 2.2.6
- Spring Integration JPA 2.2.6
我做错了什么?
英文:
I've a table that has these kind of relationship:
parent
| \
child1 child1
/ \
grandchild1 grandchild2
I called grandchildren, children and parent just for illustrate the problem.. isn't a inheritance problem
@Entity
@Table(name = “parent")
@Data
@EqualsAndHashCode(callSuper = true, exclude = { “..." })
@ToString(exclude = { “..." })
@NoArgsConstructor
public class Parent {
private static final long serialVersionUID = 1L;
@OneToMany(mappedBy = “parent")
@Cascade({org.hibernate.annotations.CascadeType.ALL})
private Set<Child> children;
}
Child.java
@Entity
@Table(name = “child")
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class Child {
private static final long serialVersionUID = 1L;
@ManyToOne
@JoinColumn(name = “parent_id")
private Parent parent;
@OneToMany(mappedBy = “child")
@Cascade({org.hibernate.annotations.CascadeType.ALL})
@LazyCollection(LazyCollectionOption.FALSE)
private List<Grandchild> grandchildren = new ArrayList<>();
}
I'm trying to delete a parent directly and with CascadeType.ALL I don't see any problem. But when I tried to delete I got:
> 08-26 11:36:33,755 ERROR [SqlExceptionHelper] Cannot delete or update
> a parent row: a foreign key constraint fails (database
.child
,
> CONSTRAINT FK_abcdefg12345
FOREIGN KEY (parent_id
) REFERENCES
> parent_id
(id
)) 2020-08-26 11:36:33,773 INFO [AbstractBatchImpl ]
> HHH000010: On release of batch it still contained JDBC statements
> 26-Aug-2020 11:36:33.776 WARNING [http-nio-8080-exec-6]
> com.sun.faces.lifecycle.InvokeApplicationPhase.execute #{delete()}:
> org.springframework.dao.DataIntegrityViolationException: could not
> execute statement; SQL [n/a]; constraint [null]; nested exception is
> org.hibernate.exception.ConstraintViolationException: could not
> execute statement
I thought that could be a mistake in import CascadeType from JPA instead of CascadeType from org.hibernate. I also tried uses only JPA code like @OneToMany(mappedBy = "parent", orphanRemoval = true, cascade = CascadeType.ALL) and didn't work.
Code
parent.setChildren(null);
parentRepository.delete(parent); //throws the exception
Dependencies
- Spring Data JPA 1.7.0
- Hibernate 4.2.1.Final
- Spring Integration JDBC 2.2.6
- Spring Integration JPA 2.2.6
What am I doing wrong?
答案1
得分: 1
即使关系被定义为双向的,级联删除始终是单向的。
当您从被外键引用的主表中删除条目时,引用该条目的条目将被删除。
我会在您已经用JoinColumn注释的属性中建立级联删除,而不是在映射的属性中。
通过删除祖父,他的子代和孙子应该被删除。
英文:
Even if the relationship is defined as bidirectional, cascading delete is always one-way.
When you delete from a main table that is referred to by a foreign key, the entries that refer to that entry are deleted.
I would establish the cascade deletion in the properties that you have annotated with JoinColumn, the ones that have a name, and not in the mapped ones.
And by deleting a grandfather, his children and grandchildren should be deleted.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论