我决定使用符合以下要求的Hibernate id生成器: - 从不同的应用程序(不同的JVM)访问域时的安全ID生成 - 使用id间隔(每次需要新ID时不要查询数据库)
经过一些调查后,我选择了2个hibernate增强型标识符生成器之一,它是
org.hibernate.id.enhanced.TableGenerator
问题是这个算法在数据库中保留的不是下一个可用的值,而是下一个可用间隔的结束,所以,假设我有一个带有increment_size 10的id生成器,当我发出一个id的请求时,我收到了区间1 - 10,但在数据库中现在存储的不是值11,而是21.对于这种行为,我必须在映射到特定表的所有类中保持increment_size相同。为什么会有这种行为?有什么方法可以解决这个问题吗?
答案 0 :(得分:4)
org.hibernate.id.enhanced.TableGenerator定义了一个能够同时生成多个值的表。听起来你试图让它从多个实体的单个值生成标识符。这是由'segment_value'TableGenerator配置设置控制的,如果你想利用它。
至于价值观,没有什么可以“修复”。它没有破碎。如果您需要不同的行为,请配置不同的行为。这由一个称为优化器的东西控制,由TableGenerator的“优化器”配置设置定义。手册中对此进行了全面介绍:http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/#mapping-declaration-id具体请参阅“5.1.2.3。增强型标识符生成器”和“5.1.2.3.1。标识符生成器优化”部分。本手册没有讨论所有可用的优化器。听起来像你想要的那个被称为“pooled-lo”,就像“pooled”,但是存储lo值而不是高值。
答案 1 :(得分:1)
这篇文章很老,但对于其他可能有同样问题的帖子。
正如Steve Ebersole所说,你应该使用" pooled-lo"在你的情况下优化器。 还要检查你的hibernate版本,它应该是> = 4.3.11,因为以前的版本中有issue。
为了给出一些解释,使用pooled-lo优化器,存储在数据库中的值是下一个可用间隔的低值。
因此,如果持久存在的最后一个实体的id在[1; 10]中,则下一个可用间隔为[11,20],存储在数据库中的值将为11,正如您所期望的那样。
因此,如果你有另一个不使用hibernate的程序,甚至不知道hibernate配置中定义的增量大小,它仍然可以在不破坏序列的情况下插入实体。
所有它必须做的是以原子方式获取序列值并递增它,然后使用值retrieve(在"增量"之前)作为它想要插入的新实体id。 在我们的示例中,为了插入一行,它将序列值更新为12并添加id为11的新实体。 因此,当hibernate将在内存(10)中达到其当前间隔的最后一个id时,它将查询数据库并存储值22,以便为它自己保持id [12; 21]的新间隔。