2012-03-25 48 views
15

时产生负的ID值,我有如下定义一个类:Hibernate的使用顺序

@Id 
@SequenceGenerator(name = "SEQ_ACE_WORKERS_QUEUE_STATS_ID", sequenceName = "SEQ_ACE_WORKERS_QUEUE_STATS_ID", allocationSize = 500) 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ACE_WORKERS_QUEUE_STATS_ID") 
@Column(name = "ID") 
private long Id; 

当我们跑了它在JBoss 4.2.3它工作得很好,并产生正确的ID(从1000+开始)

现在我们转到了jboss 7.1.1,它生成负ID! (从-498开始并向上)

任何想法为什么会发生这种情况?

+1

您是否检查Oracle中的当前序列和跟踪hibernate输出,如果您看到正确的select next sequence query,并且将paste复制到sqlplus中,您会得到正确/相同/预期的结果吗? – HRgiger 2012-03-25 15:50:04

回答

24

我刚从JBoss 6.1迁移到JBoss 7.1时遇到了这个问题。

根据在JBoss AS 7.1 JPA文档(https://docs.jboss.org/author/display/AS71/JPA+Reference+Guide#JPAReferenceGuide-Persistenceunitproperties

的JBoss 7.1自动设置几个休眠特性。其中一个属性设置为hibernate.id.new_generator_mappings,它激活使用不同算法并且不向后兼容的新ID生成器。在persistence.xml文件中将此属性设置为false将恢复旧的ID生成器行为。

hibernate 4文档还包含有关新ID生成器的信息:http://docs.jboss.org/hibernate/core/4.0/manual/en-US/html_single/#mapping-declaration-id-generator

hibernate文档明确指出,新的ID生成器默认情况下未启用,但如上所述,JBoss 7.1会自动启用它们。

+0

感谢您的回答,我已经设法找到它,忘了在这里更新:( – Tomer 2012-05-20 10:27:04

+0

从Hibernate版本5.0开始,'hibernate.id.new_generator_mappings'属性默认为'true'。请参见http://docs.jboss .org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#identifiers-generators – 2017-10-28 10:50:37

12

设置在我persistence.xmlhibernate.id.new_generator_mappingsfalse只是解决我的问题的第一部分:

为了彻底解决我在@SequenceGenerator添加allocationSize1问题(这让我省略)。

30

新的行为是下列:

AllocationSize为休眠保留主键值的范围。 而且双选的seq.nextval只有在休眠消耗了这个主键范围之后才能完成。

所以你必须声明两个allocationSize(休眠)相同的值和顺序increment by(DB)

当明确设置allocationSize=500,例如on Oracle

create sequence SEQ_ACE_WORKERS_QUEUE_STATS_ID 
     MINVALUE 1 
     MAXVALUE 999999999999999999999999999 
     START WITH 1 
     INCREMENT BY 500 
     NOCACHE 
     NOCYCLE; 

否则,您会注意到由于主键冲突而从数据库中引发的负值或约束错误。

当应用程序服务器重新启动时,您会注意到最新分配的主键与重新启动时选择的“新”序列号之间的“跳转”。

最后的评论:默认值是50。所以,如果你不休眠方指定allocationSize,你必须在DB侧申报increment by 50。

+0

非常有用的答案,因为这些信息显然不在Hibernate文档中。 – 2017-10-28 12:11:57