为什么 Java Persistence API 会根据实体总数生成 ID?

Why is the Java Persistence API generating ids based on the total amount of entities?

我正在构建一个计算贷款的 Web API。这笔贷款有一份付款清单:

@Entity
public class Loan {
    
    @Id
    @GeneratedValue
    @Column(name = "id", nullable = false)
    private Long id;

    ...

    @OneToMany(cascade = CascadeType.ALL)
    private List<Payment> amortizationSchedule;

}


@Entity
public class Payment {
    @Id
    @GeneratedValue
    private Long id;

   ...

}

每当我存储这些实体时,我希望主键生成如下:

  1. 已创建贷款,生成的 id = 1
  2. 已创建贷款,生成的 id = 2
  3. 付款已创建,生成的 id = 1
  4. 付款已创建,生成的 id = 2

而是会发生以下情况:

  1. 已创建贷款,生成的 id = 1
  2. 已创建贷款,生成的 id = 2
  3. 付款已创建,生成的 id = 3
  4. 付款已创建,生成的 id = 4

为什么会这样?我怎样才能让 Java 持久性 API 将主键生成基于某个 class 的实体数量而不是实体总数?

尝试为您的世代价值添加策略

@GeneratedValue(strategy = GenerationType.IDENTITY) 

Hibernate 中的默认 @GeneratedValueAUTO,但是从 hibernate 5 开始,AUTO 的默认解释已经改变并且正在使用序列生成器。这就是为什么您看到不同 table 的连续数字的原因,因为 ID 来自相同的来源,一个序列(如果您使用的是 MySQL,我怀疑您这样做,但它不会支持 SEQUENCE,你会注意到 hibernate 已经创建了一个 table hibernate_sequence 来模拟它)。

https://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators-auto

This is the default strategy since Hibernate 5.0. [...] . When using this strategy, AUTO always resolves to SequenceStyleGenerator. If the underlying database supports sequences, then a SEQUENCE generator is used. Otherwise, a TABLE generator is going to be used instead.

要解决此问题,只需按照@CodeAddict 在他的回答中所说的进行操作,使用 @GeneratedValue(strategy = GenerationType.IDENTITY) 因此它使用 MySQL 的 AUTO_INCREMENT 功能。