在 JPA/Hibernate 中使用 @OnetoMany 的实体中不存在时从数据库中删除子记录(Spring 引导应用程序)

Posted

技术标签:

【中文标题】在 JPA/Hibernate 中使用 @OnetoMany 的实体中不存在时从数据库中删除子记录(Spring 引导应用程序)【英文标题】:Deleting child records from Database when not present in entity with @OnetoMany in JPA/Hibernate (Spring boot application) 【发布时间】:2020-06-18 02:56:17 【问题描述】:

我正在使用 JPA/Hibernate 开发一个 Spring Boot Web 应用程序。应用程序接收 JSON 格式的数据记录,这些记录映射到 @Entity 类。布局相当简单,它有一个主实体类和一组子实体。我通过@OneToMany/@ManytoOne 映射这些。使用 JpaRepository 的默认存储库功能,解析、从 DB 读取数据、在 DB 中插入/更新数据都可以正常工作......

问题是,当我收到必须更新的记录时,我只想存储请求附带的那些子记录。如果有其他子记录,这些子记录之前存储在父记录中,并且在请求的当前记录中不存在,它们有 从数据库中删除。

我的想法是通过将子记录集与从数据库接收到的子记录集进行比较,将不存在的子记录放入列表中并删除它们,然后保留实体。另一种选择是首先删除所有子记录,然后保留新实体....

我现在的问题是:难道没有更优雅的方式来使用 JPA/Hibernate 来实现这一点。一些注释或选项或其他东西。我还没有找到任何适合我的方法。你有什么想法?

更新: 我的问题不是删除父实体,然后删除子记录级联。父实体保持原样(或更新......)。我只想删除子记录,并且只删除当前请求实体中不存在但在数据库中的子记录。

一个例子: 在父表的数据库中有一条 parentID = 1 的记录。在子表中有 3 条引用的记录,其子 ID 分别为 1、2、3。

现在客户向我发送一个 parentID = 1 的实体以在数据库中更新。在子集中,只有 childID 为 1 和 2 的子实体存在。现在的任务是通过从数据库中删除 id = 3 的子记录来更新实体(无论字段中发生了什么变化)

谢谢和问候。

【问题讨论】:

【参考方案1】:

我认为这是级联您想要使用的内容。例如。 Cascase.REMOVE 会自动移除所有不再被引用的子实体。

你可以这样使用它:

@OneToMany(cascade = CascadeType.REMOVE)

可以在这里找到一个很好的概述:https://www.baeldung.com/jpa-cascade-types

【讨论】:

感谢您的回复。问题是,父记录不应被删除...我正在寻找一种方法来存储数据库中唯一存在于我当前实体子集中的子集。使用 Cascade.type remove 我可以删除所有子项的整个父记录,然后再次保留整个实体,但在我看来这似乎是一种丑陋的方法

以上是关于在 JPA/Hibernate 中使用 @OnetoMany 的实体中不存在时从数据库中删除子记录(Spring 引导应用程序)的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 JPA 2/Hibernate 中使用共享主键时实体需要可序列化?

数据在数据库 jpa/hibernate 中插入两次

在 merge() 操作中丢失复合外键(JPA/Hibernate)

如何在 JPA/Hibernate 中执行本机 SQL 脚本?

Jpa , Hibernate 选择查询优化

使用 JPA / Hibernate 在无状态应用程序中进行乐观锁定