首页 > 解决方案 > 如何在 JPA/Hibernate 中保持唯一的关系被持久化/合并到数据库

问题描述

示例:我有一个 Person 实体,它与 Citizenship 实体具有多对多关系。个人实体:

    // annotations
    @Entity
    public class Person {

      // ...
      @ManyToMany(
        fetch = FetchType.LAZY,
        cascade = {CascadeType.PERSIST, CascadeType.MERGE}
      )
      @JoinTable(
        name = "persons_citizenships",
        joinColumns = {@JoinColumn(name = "PERSON_ID")},
        inverseJoinColumns = {@JoinColumn(name = "CITIZENSHIP_ID")}
      )
      private Set<Citizenship> citizenships = new HashSet<>();
      // ...
      // setters and getters
    }

和公民实体:

    // annotations
    @Entity
    public class Citizenship {

      @ManyToOne
      private Country country;
    }

现在问题如下:如果我在 REST 服务中接收到 Person 更新的对象,并且如果我得到以下从 json 序列化的 Person 对象:

{
  "id": 2,
  "firstName": "Johnny",
  "citizenship": [
    {
      "id": 2,
      "country": {
        "id": 128
      }
    }
  ]
}

一切顺利,人员更新。但是,如果有人调用我的服务,但没有提供 Citizenship 对象的所有信息,例如国家/地区 ID,则会出现问题。在这种情况下,当 JPA 合并该实体时,它会级联为公民身份并将国家 ID 设置为 null,这对我来说是一个很大的禁忌。此案例的示例 JSON:

{
  "id": 2,
  "firstName": "Johnny",
  "citizenship": [
    {
      "id": 2
    }
  ]
}

我能做些什么来确保只有RELATIONS被持久化/合并,而不是子实体本身。我的意思是公民身份不会改变,我的服务用户不应该通过个人更新来改变它。是的,我知道 CascadeType.MERGE 会这样做,但如果我删除它,那么即使关系也不会保存。如果在任何需要的解决方案中,我也不想使用 CascadeType.ALL(在任何情况下都包括 CascadeType.REMOVE,因为它有危险的副作用,PS 我之前经历过)。

请提出一些建议来验证这种情况。这对我的应用程序来说是一个明显的安全问题,并且不想依赖我的服务用户的意图......

标签: javaspringhibernaterestjpa

解决方案


推荐阅读