如何防止 Hibernate 删除 JSON 帖子中不存在的子对象?

Posted

技术标签:

【中文标题】如何防止 Hibernate 删除 JSON 帖子中不存在的子对象?【英文标题】:How do I prevent Hibernate from deleting child objects not present in a JSON post? 【发布时间】:2016-10-07 11:38:58 【问题描述】:

我有一个 JPA Property 实体,它有孩子(多个 Rate 和多个 Reservation)。在我的 javascript 应用程序中,我通过 REST property:rates:[...], reservations[...] 拉动 JSON。 Rates and Reservations 非常冗长,所以当我发布属性更新(比如更改名称)时,我会从JSON POST 有效负载中删除rates 和reservations。我希望 Hibernate 会简单地忽略丢失的键,但是,它正在删除所有保存的孩子。如果它们不存在,我如何指定 Hibernate 忽略它们?

@Entity
public class Property 

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    String name;

    @OneToMany(mappedBy = "property", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @JsonManagedReference
    private Set<SeasonRate> rates = new HashSet<>();

    @OneToMany(mappedBy = "property", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
    private Set<Reservation> reservations = new HashSet<>();


Ps:我对级联的理解有限,但我确实想要这样的功能,即如果有人删除一个属性,它必须删除费率和预订。不过,我无法通过完整的属性保存来更新价格或预订,所以也许我应该只使用 CASCADE=UPDATE?价格有自己的更新机制,预订也有。

【问题讨论】:

JSON 如何解组到实体? @AlanHay,在 Spring Boot 中使用默认的 Jackson Marshaller 【参考方案1】:

迟到的答案,但是如果您使用 Spring MVC Rest 控制器而不是 Spring Data Rest 控制器来处理更新,那么看起来前者不支持部分更新/补丁请求。

使用通过表单直接修改实体的传统非 RESTful Web 应用程序当然是可能的。例如:

@RequestMapping
public String updateEntity(@ModelAttribute myEntity)
  //submitted form parameters merged to existing entity 
  //loaded via getMyEntity() leaving unmodified fields as they were


@ModelAttribute
public MyEntity getMyEntity()
  //load some existing entity
 

但是,当通过 @RequestBody 将 JSON 绑定到实体时,这是不可能的:

@RequestMapping
public String updateEntity(@RequestBody myEntity)
  //new instance instantiated by the Jackson mapper
  //missing fields will be null

围绕这个有一些出色的 JIRA:

https://jira.spring.io/browse/SPR-13127

https://jira.spring.io/browse/SPR-10552

https://jira.spring.io/browse/SPR-13127

以及各种 SO 问题:

Spring Partial Update Object Data Binding

不过,好消息是 Spring Data Rest 确实支持通过补丁进行部分更新,因此如果可以选择将存储库公开为 Rest 存储库,那么您应该能够实现所需的行为:

https://spring.io/guides/gs/accessing-data-rest/

PUT 替换整个记录。未提供的字段将被替换 与空。 PATCH 可用于更新项目子集

【讨论】:

以上是关于如何防止 Hibernate 删除 JSON 帖子中不存在的子对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 Hibernate 更新 NULL 值

当jackson序列化json对象时如何防止hibernate5延迟获取?

如何防止VSCode自动格式删除json文件末尾的新行?

错误:列是 json 类型,但表达式在 Hibernate 中是不同的字符类型

如何防止出现 org.hibernate.loader.MultipleBagFetchException

如何使用 JPA 和 Hibernate 防止 SQL 注入?