使用Oracle序列的Hibernate不使用它

Vla*_*ada 20 hibernate sequence id-generation

我已经配置了hibernate来使用oracle序列.使用cache = 20,increment = 1创建序列.

一切正常,hibernate持久化实体.id值很奇怪:50,51 .... 76,201,202 ... 209,1008,1009,5129,5130 ....

如果我要求序列值(从双重中选择hibernate_sequence.nextval),我得到的值就像2,3,4 ....

如果我打开hibernate sql debug,有时间调用"从双重选择hibernate_sequence.nextval",但是由hibernate分配给ID的号码不会按顺序中继!

@Id
@Column(name = "ID", insertable = false, updatable = false)
@SequenceGenerator(name = "SequenceIdGenerator", sequenceName = "HIBERNATE_SEQUENCE")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SequenceIdGenerator")
private Long id;
Run Code Online (Sandbox Code Playgroud)

JB *_*zet 33

这是因为SequenceGenerator实际上不是序列生成器.这是一个序列hi-lo发生器.这意味着第一次调用它时,它从序列中获取下一个值(例如6),然后将该值乘以50并得到结果(300).下次调用时,它返回301(不进入序列),依此类推,直到达到349.然后它会询问序列的下一个值并获得7,它再次乘以50得到350.我的算法描述可能是一个人,但你明白了.

如果停止并启动应用程序,则会产生间隙.但它比纯序列生成器更有效,因为它只在50代中进行一次数据库调用.

请参阅http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#mapping-declaration-id-enhanced-optimizers和http://docs.jboss.org/hibernate/core/ 3.6/reference/en-US/html_single /#mapping-declaration-id-generator有关详细信息.

  • 您不必每次增加50.这只是默认值.使用@SequenceGenerator(name ="SEQ_ID",sequenceName ="SEQ_ID",allocationSize = 1)仅增加一个.allocationSize是关键. (11认同)
  • 无论如何不使用它?因为它对我来说是个大问题,所以让其他触发器对这个表使用相同的序列.然后他们将来可能会打这个号码吧? (2认同)

ben*_*y23 6

我认为你的问题是数据库中ID列的值不是一个自然的序列,但是为什么你会看到差距:

一点背景:

  • 每次调用select HIBERNATE_SEQUENCE.nextval from DUAL序列的值都会增加.
  • 由于您的序列名称是通用的而不是特定于表,如果您有多个实体都使用HIBERNATE_SEQUENCE作为id生成器,那么序列中的值将用于所有实体.
  • 如果某个其他应用程序使用HIBERNATE_SEQUENCE,则也会跳过该值.
  • 当您使用CACHE = 20时,Oracle将以20个块的形式获取序列号,然后使用内部缓存返回数字.如果缓存丢失(例如,如果DB关闭),这可能导致跳过数字.
  • 如果从数据库中删除行,则序列值不会更改

例如,请考虑以下情形:

你有两个实体Entity1和Entity2使用HIBERNATE_SEQUENCE作为ID生成器:

  1. 当前HIBERNATE_SEQUENCE值为100
  2. 插入一个Entity1(使用返回101的HIBERNATE_SEQUENCE)
  3. 插入一个Entity2(使用返回102的HIBERNATE_SEQUENCE)
  4. 插入一个Entity2(使用返回103的HIBERNATE_SEQUENCE)
  5. ID为103的Entity2将被删除
  6. 你手动执行select HIBERNATE_SEQUENCE.nextval from DUAL(返回104)
  7. 插入一个Entity1(使用返回105的HIBERNATE_SEQUENCE)
  8. 插入一个Entity2(使用返回106的HIBERNATE_SEQUENCE)

所以在它结束时你将拥有:

  • 带ID的实体1(101,105)
  • 具有ID的实体2(102,106)

这解释了差距.

编辑:

即使@SequenceGenerator被设置为使用SequenceGenerator而不是SequenceHiLoGenerator(正如JB Nizet指出的那样,我认为这是间隙的更好解释),序列生成的ID中的间隙是常见的.