Sea*_*lly 4 java oracle spring hibernate sequence
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
Run Code Online (Sandbox Code Playgroud)
第一个“获得的序列值”是正确的,22643MY_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;
Run Code Online (Sandbox Code Playgroud)
如果有帮助,我可以包含我的 Spring Hibernate 上下文配置。我没有看到任何看起来明显相关的东西。
Hibernate with Oracle 序列不使用它很可能是相关的,但是当我获得的 id小于获得的序列值时,它会处理间隙。
PS:其他票讨论了优化效率的序列生成器策略。此数据的单个记录大约每个月插入一次,并且仅来自此类。所以,效率在这里不是问题。
我也可以在 Oracle 仿真模式下在 HSQLDB 中重新创建它。所以这肯定是一个Hibernate问题。
偏移量始终正好是 49。上面的示例正确地从序列中获取了 22643,但随后将 22594 解析为下一个值。
22643-22594=49
在另一个例子中,下一个序列值实际上是 4,Hibernate 给了我 -45。
4-(-45)=49
后续插入不会调用 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
Run Code Online (Sandbox Code Playgroud)
正如我在第三次更新中提到的,JPA 正在从序列中“获取 50 个 id”,并在内存中对它们进行计数以提高效率。
此行为由javax.persistence.SequenceGenerator.allocationSize默认为 50指定。
(可选)从序列中分配序列号时要增加的数量。
这对我或其他人来说一点也不直观,因为我的 Oracle 数据库序列应该定义这种行为,而 50 不是那里的标准默认值。
快速而肮脏的解决方案是指定allocationSize=1:
@SequenceGenerator(name = "generator", sequenceName = "MY_SEQ",
allocationSize = 1)
Run Code Online (Sandbox Code Playgroud)
现在每次插入都会增加 Oracle 序列。
| 归档时间: |
|
| 查看次数: |
5548 次 |
| 最近记录: |