【问题标题】:JPA populate a composite key id part from parent entityJPA 从父实体填充复合键 id 部分
【发布时间】:2021-04-15 17:43:43
【问题描述】:

假设我有这两个实体,个人和保险。一个人可以拥有多份保险,保险唯一性由(保险类型、保单编号和人员 ID)的复合键组合维护。下面的代码代表场景...

父类

@Entity
@Setter
@Getter
@RequiredArgsConstructor
public class Person implements Serializable {

  @Id
  @GeneratedValue(strategy = "GenerationType.IDENTITY")
  @Column(name "person_id")
  private Long personId;

  @Column(name = "fst_nm")
  private String fstName;

  @Column(name = "lst_nm")
  private String lstNm;
  
  // ..Other columns & relationships
  
  @OneToMany(mappedBy = "person")
  private List<Insurance> insurances;

  public void addInsurance(Insurance toAdd) {
    getInsurances().add(toAdd);
    toAdd.setPerson(this);
  }
}

子类

@Entity
@Setter
@Getter
@RequiredArgsConstructor
public class Insurance implements Serializable {

  @EmbeddedId
  private insurancePK id;

  //other data

  @ManyToOne
  @MapsId("personId")
  private Person person;
}

复合PK类

@Setter
@Getter
@Embeddable
public class InsurancePK implements Serializable {

  @Column(name = "person_id", insertable = false, updatable = false)
  private Long personId;

  @Column(name = "insurance_type")
  private String insuranceType;

  @Column(name = "pol_num")
  private String polNum;
}

现在,我的数据映射器看起来像这样......

  Person newPerson = new Person();
  newPerson.setInsurances(new ArrayList<>());

  // fill out Person Model data

  // incoming insurance data
  while (incomingData.hasNext()) {
    Insurance insuranceData = new Insurance();
    InsurancePK pk = new InsurancePK();

    // set other insurance data

    pk.setInsuranceType("Dental");
    pk.setPolNum("123Abc00");

    insuranceData.setId(pk);
    person.addInsurance(insuranceData);
  }

问题是我在复合键中的 person_id 总是得到一个空值,不知道为什么(@MapsId 不应该处理那个值)? 我需要动态获取该值,大多数 JPA 复合键解决方案只是手动设置所有值,但这不是我的方案。

从 saveAndflush() 返回对象

{
  person: {
    person_id: 55,
    fst_nm: blah,
    lst_nm: blah,
    insurances: [
      {
        insurance_pk: {
          person_id: null,
          insurance_type: "Dental",
          pol_num: "123Abc00"
        }
       //other insurance data
      }
    ]
  }
}

关于我缺少什么的任何建议?提前谢谢!

【问题讨论】:

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


【解决方案1】:
  1. InsurancePK.personId 中删除@Column(name = "person_id", insertable = false, updatable = false) 注释。

  2. 添加以下注释:

@JoinColumn(name = "name = "person_id"")

Insurance.person

【讨论】:

  • 删除注释并添加@JoinColumn(name = "name = \"person_id\""); 也不起作用!
  • 您没有展示如何保存实体。如果您使用例如entityManager.persist(newPerson),那么您还应该添加适当的级联@OneToMany(mappedBy = "person", cascade = CascadeType.PERSIST)
  • 那是关于添加级联的一个很好的指导,它让我在正确的轨道上解决了我的问题。谢谢!
【解决方案2】:

正如 cmets 中所述,向我的实体列添加级联使我走上了正轨。 以防万一,这是经过几次尝试后对我有用的模型

父类

@Entity
@Setter
@Getter
@RequiredArgsConstructor
public class Person implements Serializable {

  @Id
  @GeneratedValue(strategy = "GenerationType.IDENTITY")
  @Column(name "person_id")
  private Long personId;

  @Column(name = "fst_nm")
  private String fstName;

  @Column(name = "lst_nm")
  private String lstNm;
  
  // ..Other columns & relationships
  
  // cascade added  <-- thanks to SternK
  @OneToMany(mappedBy = "person", casecade = CascadeType.ALL, orphanRemoval = true)
  private List<Insurance> insurances;

  public void addInsurance(Insurance toAdd) {
    getInsurances().add(toAdd);
    toAdd.setPerson(this);
  }
}

儿童班

@Entity
@Setter
@Getter
@RequiredArgsConstructor
public class Insurance implements Serializable {

  @EmbeddedId
  private insurancePK id;

  //other data

  @ManyToOne
  @MapsId("personId")
  // annotation added here instead of PK class  <-- fix
  @JoinColumn(name="person_id", nullable = false, insertable = false, updatable = false)
  private Person person;
}

PK类

@Setter
@Getter
@Embeddable
public class InsurancePK implements Serializable {
  //annotation removed  <-- fix thanks to SternK
  private Long personId;

  @Column(name = "insurance_type")
  private String insuranceType;

  @Column(name = "pol_num")
  private String polNum;
}

【讨论】:

    猜你喜欢
    • 2011-12-12
    • 1970-01-01
    • 2020-05-19
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多