gpt4 book ai didi

java - Hibernate 序列 nextVal 已解析但未使用 (Oracle)

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:05:27 26 4
gpt4 key购买 nike

Hibernate 没有按预期分配来自 Oracle 序列的对象 ID。这是我在 Hibernate 调试日志中看到的内容。

DEBUG o.h.SQL:92 - select MY_SEQ.nextval from dual
DEBUG o.h.i.e.SequenceStructure:102 - Sequence value obtained: 22643
DEBUG o.h.r.j.i.ResourceRegistryStandardImpl:73 - HHH000387: ResultSet's statement was not registered
DEBUG o.h.e.i.AbstractSaveEventListener:118 - Generated identifier: 22594, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator

第一个“获得的序列值”是正确的,正如它所说,22643 来自 MY_SEQ.nextVal。但是随后使用的“生成的标识符”是 22594。是什么原因?

我试过调整生成器策略但无济于事。

@Id
@SequenceGenerator(name = "generator", sequenceName = "MY_SEQ")
@GeneratedValue(generator = "generator", strategy = GenerationType.SEQUENCE)
@Column(name = "MY_ID", nullable = false, precision = 6, scale = 0)
private Integer id;

如果有帮助,我可以包括我的 Spring Hibernate 上下文配置。我没有在其中看到任何看起来明显相关的内容。

Hibernate with Oracle sequence doesn't use it很可能是相关的,但是当我得到的 id 小于得到的序列值时,它处理了间隙。

PS:其他工单讨论优化效率的序列生成器策略。此数据的单个记录大约每月插入一次,并且仅来自此类。因此,效率在这里不是问题。

更新1

我也能够在 Oracle 仿真模式下在 HSQLDB 中重新创建它。所以这肯定是一个 Hibernate 问题。

更新2

偏移量始终恰好为 49。上面的示例正确地从序列中获取了 22643,但随后将 22594 解析为下一个值。

22643-22594=49

在另一个例子中,下一个序列值实际上是 4,而 Hibernate 给了我 -45。

4-(-45)=49

更新3

后续插入不会调用 Oracle 序列的 nextVal。我怀疑 JPA/Hibernate 正在尝试预先批量获取 ID 以提高效率。

DEBUG o.h.SQL:92 - select MY_SEQ.nextval from dual
DEBUG o.h.i.e.SequenceStructure:102 - Sequence value obtained: 22643
DEBUG o.h.r.j.i.ResourceRegistryStandardImpl:73 - HHH000387: ResultSet's statement was not registered
DEBUG o.h.e.i.AbstractSaveEventListener:118 - Generated identifier: 22594, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator
...
DEBUG o.h.e.i.AbstractSaveEventListener:118 - Generated identifier: 22595, using strategy: org.hibernate.id.enhanced.SequenceStyleGenerator

最佳答案

正如我在第 3 次更新中提到的,JPA 预先从序列中“获取 50 个 ID”并在内存中对它们进行计数以提高效率。

此行为由 javax.persistence.SequenceGenerator.allocationSize 指定,默认为 50。

(Optional) The amount to increment by when allocating sequence numbers from the sequence.

这对我来说一点都不直观,or others ,因为我的 Oracle 数据库序列应该定义此行为,而 50 不是那里的标准默认值。

快速而肮脏的解决方案是指定 allocationSize=1:

@SequenceGenerator(name = "generator", sequenceName = "MY_SEQ",
allocationSize = 1)

现在每次插入时 Oracle 序列都会递增。

关于java - Hibernate 序列 nextVal 已解析但未使用 (Oracle),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38578770/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com