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

时间:2016-06-07 14:01:07

标签: java spring hibernate jpa spring-data-jpa

我有一个有孩子的JPA Property实体(多个Rate和多个Reservation)。在我的JavaScript应用程序中,我通过JSON REST提取{property:{rates:[...], reservations[...]}。费率和预订非常详细,因此当我发布属性更新(如更改名称)时,我会从JSON POST有效负载中删除费率和预订。我希望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?费率有自己的更新机制,预订也是如此。

1 个答案:

答案 0 :(得分:0)

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

使用传统的非平静网络应用程序直接通过表单修改实体,这当然是可能的。例如:

@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 Repository的选项,那么您应该能够实现所需的行为:

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

  

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