【问题标题】:Spring boot JPA - primary key of entities in databaseSpring boot JPA - 数据库中实体的主键
【发布时间】:2021-02-08 13:29:29
【问题描述】:

我在父实体和子实体之间有@OneToMany@ManyToOne 关系。

@Entity
@Table(name = "parent")
public class Parent {

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


@OneToMany(targetEntity=Measurement.class, mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
@JsonManagedReference
private List<Child> children = new ArrayList<>();
}

我有这样的子实体

@Entity
@Table(name = "child")
public class Child {

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

@ManyToOne(targetEntity=Parent.class, fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
@JsonBackReference
private Parent parent;

保存此数据后,数据库如下所示,

Parent:
 id
 1

 Child
 id     parent_id
 2      1

我的问题是,为什么孩子的主键是 2 而不是 1?在子表中,它可以有一个主键为 1,外键引用父级为 1。当我再添加一个父表时,表看起来像这样,

Parent:
 id
 1
 3

 Child
 id     parent_id
 2      1
 4      3    

我做错了什么还是预期的行为?

【问题讨论】:

  • Parent.children 中删除@PrimaryKeyJoinColumn 注释。

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


【解决方案1】:

生成策略@GeneratedValue(strategy = GenerationType.AUTO) 将从默认的hibernate sequence 中获取值,因此所有密钥生成都使用相同的序列。

当您插入数据时,它会像 Parent 然后 Child 一样按顺序插入,因为它从同一个序列生成器中获取值,它会按顺序增加所有表。

您需要使用GenerationType.IDENTITY 策略来达到您的目的。

在父级父级中

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

在孩子中

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

【讨论】:

    猜你喜欢
    • 2020-07-04
    • 1970-01-01
    • 2017-03-08
    • 1970-01-01
    • 1970-01-01
    • 2018-12-27
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    相关资源
    最近更新 更多