Hibernate序列nextVal已解决但未使用(Oracle)

时间:2016-07-25 23:13:10

标签: java spring oracle 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

第一个“获得的序列值”是正确的,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:其他票据讨论了优化效率的序列生成器策略。此数据的单个记录每月插入一次,并且仅从此类插入。因此,效率不是一个问题。

更新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

1 个答案:

答案 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序列。