2012-03-25 21 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