当前位置: 首页 > 知识库问答 >
问题:

OneToMany关系与复合主键级联

别宏盛
2023-03-14

我正在使用JPA(Hibernate)并试图用childs和复合键持久化整个新实体,但当持久化childs时,我在键中得到了null。表结构:

CREATE TABLE IDENTITY_DOCS
(
    PERSON_ID BIGINT NOT NULL,
    DOC_TYPE_ID BIGINT NOT NULL,
    ...
);

CREATE TABLE DOC_TYPES
(
    DOC_TYPE_ID BIGINT PRIMARY KEY NOT NULL,
    ...
);

CREATE TABLE PERSONS
(
    PERSON_ID BIGINT PRIMARY KEY NOT NULL,
    ...
);

映射:

@IdClass(...IdentityDocsPK.class)
@Table(name = "IDENTITY_DOCS")
@Entity
public class IdentityDocs {

    @Id
    @Column(name = "PERSON_ID", nullable = false)
    private Long personId;

    @Id
    @Column(name = "DOC_TYPE_ID")
    private Long docTypeId;

    @ManyToOne
    @MapsId("personId")
    @JoinColumn(name = "PERSON_ID", referencedColumnName = "PERSON_ID")
    private Employee employee;
    ...
}

public class IdentityDocsPK implements Serializable {

    private Long personId;

    private Long docTypeId;
    ...
}

@Table(name = "PERSONS")
@Entity
@Where(clause = "PERSON_TYPE_ID = 1")
public class Employee {

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "PERSON_ID")
    @Id
    private Long personId;
    ...
    @OneToMany(mappedBy = "employee", fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
    private List<IdentityDocs> identityDocs;
}

@Table(name = "DOC_TYPES")
@Entity
public class DocTypes {

    @Id
    @Column(name = "DOC_TYPE_ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long docTypeId;
    ...
}
Employee employee = new Employee();
employee.setFirstName("AAAA");
employee.setLastName("BBBB");
employee.setPersonNumber("1337");

IdentityDocs docs1 = new IdentityDocs();
docs1.setDocTypeId(1L); // already in database
docs1.setDocNumber("11111");
docs1.setDocSeries("11111");
docs1.setPlaceIssue("1111");

employee.setIdentityDocs(new ArrayList<IdentityDocs>());
employee.getIdentityDocs().add(docs1);

em.persist(employee); 
NULL not allowed for column "PERSON_ID"; SQL statement:
insert into IDENTITY_DOCS (DATE_EXPIRED, DATE_ISSUE, DOC_NUMBER, DOC_SERIES, PLACE_ISSUE, DOC_TYPE_ID, PERSON_ID) values (?, ?, ?, ?, ?, ?, ?) 

共有1个答案

蒋永宁
2023-03-14

也许应该在DDL中的person_id字段上有一个AUTO_INCERMENT子句,或者以其他方式生成密钥。

 类似资料:
  • 问题内容: 我正在使用带有注释的Hibernate(在spring),并且我有一个对象,该对象具有有序的多对一关系,该对象的子对象具有复合主键,该子对象的一个​​组成部分是返回到该对象的外键。父对象的ID。 结构看起来像这样: 我尝试了各种注释的组合,但似乎都不起作用。这是我能想到的最接近的: 经过长时间的实验后,我得出了这一结论,在该尝试中,我进行的其他大多数尝试都产生了由于各种原因甚至无法加载

  • 它应该允许独立地更新表,并在父行被删除时删除子行。

  • 我在将带有@ManyToOne关系的实体(雇员)映射到带有@OneToMany关系的实体(社区)时遇到了问题。 当我将一个实体(社区)分配给一个实体(员工),其中社区的值为空时,它工作正常。 问题出现了,如果雇员已经为社区分配了价值。当我更改该值并保存更改时,该员工为社区获得了新的值,并且这个新社区在集合中获得了该员工。唯一的问题是,老社区仍然有这个员工在收集,但它应该被删除。这只有在数据库重新启

  • 我用复合键定义了两个实体之间的多对多关系。问题是,当我获得join对象时,它只被过滤了关系的一侧,而不是两边。 图片使问题更加清晰。这里,我要查找的是dtid=185和prid=352,但我从多对多关系中得到的是两个突出显示的行。 天丁:

  • 问题内容: 我的应用程序中已有一个父子关系,但由于我们在父子的主键中都添加了“类型”列,因此该关系最近变得更加复杂。在此之后,添加,阅读和修改儿童效果很好,但是删除它们很痛苦。 使用Vlad Mihalcea在本文中针对@OneToMany关系给出的建议以及组合键上的各种示例,我尝试了一种类似于以下模型的实现。但是,删除孩子仍然无法正常工作,现在我得到了一个奇怪的错误消息作为奖励。 我正在使用Sp

  • 我有两个实体的订单和项目。在Order entity中,id是OrderId、UserId的复合主键,但在Items中,外键仅为Order id。 如何使用订单Id获取项目列表 我尝试使用mappedBy,如上所述,无论在哪种情况下,我都得到了错误。 任何帮助都是非常感谢的。