JPA 中的级联设置和休眠中的外键违规

Ban*_*nny 2 java entities hibernate jpa cascade

我有两门课:

  1. 家长
  2. 孩子

数据库中的Child表有一列ParentId -> 典型的One(Parent)-> Many(Children)关系

现在我创建两个实体,它们

public class Parent
{
    @OneToMany(mappedBy="Parent", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    public Set<Child> getChildern()
    {
      ...
    }
}

public class Child
{
   @ManyToOne(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
   @JoinColumn(name="ParentId")
   public Parent getParent()
   { ... }
}
Run Code Online (Sandbox Code Playgroud)

现在我有两种情况:

  1. 父级被删除 -> 会发生什么?
  2. 子项被删除 -> 会发生什么?

奖励问题:

  1. 我是否总是需要创建密钥 OneToMany 和 ManyToOne 的两个部分,或者我可以只拥有 ManyToOne 并且不关心我有孩子的父级?
  2. 什么会导致休眠给我一条没有孩子的父母违反外键约束的消息?

Mar*_*tör 5

首先,我很惊讶这段代码竟然能工作。IMOmappedBy="Parent"实际上应该是mappedBy="parent"(注意小写的“p”),因为该类的父属性Child被称为parent而不是Parent

其次,我建议您将注释放在属性上而不是访问器方法上。我发现它使整个代码

您的问题的答案取决于您所说的“被删除”的确切含义。我假设你的意思是“通过持久性管理器删除”。

但万一您期望/希望 JPA 提供程序删除子级,那么parent.getChildren().remove(x)您需要设置orphanRemoval = "true"on OneToMany

问题1

父级和所有子级都被删除。这是常见的情况。

问题2

父级和所有子级都被删除。这是一个相当奇怪的用例。通常级联删除仅适用于一对多关系。

奖金1

Java 和 JPA 中的所有关系都是单向的,因为如果源对象引用目标对象,则不能保证目标对象也与源对象有关系。

来自优秀的Java Persistence wiki 书籍

奖金2

不知道。是ConstraintViolationException来自底层数据库吗?或者换句话说,两个表的 DDL 是什么样的?它是由 Hibernate 生成的吗?