为什么我使用了CascadeType.ALL,却仍然收到DataIntegrityViolationException错误?

huangapple go评论72阅读模式
英文:

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&quot;)
@Data
@EqualsAndHashCode(callSuper = true, exclude = { “...&quot; })
@ToString(exclude = { “...&quot; })
@NoArgsConstructor
public class Parent {

   private static final long serialVersionUID = 1L;

   @OneToMany(mappedBy = “parent&quot;)
   @Cascade({org.hibernate.annotations.CascadeType.ALL})
   private Set&lt;Child&gt; children; 
}

Child.java

@Entity
@Table(name = “child&quot;)
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class Child {

   private static final long serialVersionUID = 1L;
   
   @ManyToOne
   @JoinColumn(name = “parent_id&quot;)
   private Parent parent;
   
   @OneToMany(mappedBy = “child&quot;)
   @Cascade({org.hibernate.annotations.CascadeType.ALL})
   @LazyCollection(LazyCollectionOption.FALSE)
   private List&lt;Grandchild&gt; grandchildren = new ArrayList&lt;&gt;();
   
}

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.

huangapple
  • 本文由 发表于 2020年8月26日 23:37:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/63601015.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定