【问题标题】:Hibernate: Deleting parent entity triggers update query on childrenHibernate:删除父实体触发对子实体的更新查询
【发布时间】:2019-03-28 13:43:44
【问题描述】:

情况

我有一对父子 JPA 实体。 父级称为 JobTemplate 并将子级称为:

@OneToMany(cascade = {CascadeType.MERGE,CascadeType.PERSIST}, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinColumn(name = "job_template_id")
private List<ChecklistTemplateEntry> checklistEntries = new ArrayList<>();

孩子被称为 ChecklistTemplateEntry 并像这样引用它的父母:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "job_template_id")
private JobTemplate jobTemplate;

在 mySQL 服务器中,有一个级联设置。子表的创建命令说明:

 FOREIGN KEY (job_template_id) REFERENCES job_template(id) ON DELETE CASCADE 

如果我通过手动输入 sql 命令删除实体,级联工作正常。

问题

当我尝试通过调用 JPA(spring boot 存储库)删除父实体时

jobTemplateRepo.delete(jobTemplateToDelete); //from CrudRepository

JPA 触发对子表的更新查询:

update checklist_template_entry set job_template_id=null where job_template_id=?

mySQL 不接受这个查询,因为 job_template_id 有一个 NOT NULL 规则(有充分的理由)。 结果是我无法删除我的实体。我明白了:

java.sql.SQLException: Column 'job_template_id' cannot be null

目标

我想在创建/更新操作中使用从父级到子级的 JPA。但是在删除父实体时,我希望 JPA 仅触发对该实体的删除查询,而不尝试更新子实体,因为这会导致问题,而 mySQL 无论如何都会解决这个问题。

我的尝试

  • 级联的各种组合,包括 ALL、除 remove 之外的所有组合等。
  • 在两侧启用/禁用延迟加载。

【问题讨论】:

  • 我认为你错过了双向一侧的“mappedBy”参数
  • @MartinFrey 你刚刚拯救了我的一天!在父实体类的 OneToMany 注释中用 mappedBy 参数替换 JoinColumn 注释解决了我的问题。
  • 您是否尝试将 orphanRemoval = true 改为 orphanRemoval = false?数据库现在正在处理这个问题。
  • @MartinFrey 您能否将其发布为答案,以便我将其标记为已接受的答案?谢谢
  • @PeterHe 如果我没记错的话,orphanRemoval 对于更新操作很有用,以防您从集合中删除实体。我需要这个功能......

标签: mysql spring hibernate cascade


【解决方案1】:

您错过了双向注释一侧的“mappedBy”参数,有效地创建了两个单向关系。 将一侧的 JoinColumn 替换为 mappedBy 参数,您应该会得到正确的删除语句。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-04
    • 1970-01-01
    • 2020-06-06
    • 2017-10-31
    • 1970-01-01
    • 2020-04-29
    • 2021-12-20
    相关资源
    最近更新 更多