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是 less 而不是获得的序列值。
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
答案 0 :(得分:2)
正如我在第3次更新中提到的那样,JPA从前面的序列中“取出50个ID”并在内存中计算它们以提高效率。
此行为由javax.persistence.SequenceGenerator.allocationSize
指定,默认为50。
(可选)从序列中分配序列号时的增量。
这对我来说并不直观,or others,因为我的Oracle数据库序列应该定义这种行为而50不是那里的标准默认值。
快速而肮脏的解决方案是指定allocationSize=1
:
@SequenceGenerator(name = "generator", sequenceName = "MY_SEQ",
allocationSize = 1)
现在每个插入都会增加Oracle序列。