2013-08-27 64 views
13

我有一個問題,我無法得到我的頭。在Hibernate中我有以下沒有問題:EclipseLink和序列生成器預分配

@GeneratedValue(strategy = GenerationType.AUTO, generator = "email-seq-gen") 
@SequenceGenerator(name="email-seq-gen", sequenceName="EMAIL_SEQ_GEN", allocationSize=500) 

然後在我的schema.ddl我有這樣的:

CREATE SEQUENCE EMAIL_SEQ_GEN START 1 INCREMENT 500; 

沒有太多的看這裏。一切都按預期工作。但是,如果將我的供應商的EclipseLink我得到這個錯誤:

The sequence named [EMAIL_SEQ_GEN] is setup incorrectly. Its increment does not match its pre-allocation size. 

所以我當然是谷歌四周,看到一些有關的EclipseLink創建一個負數,如果初始值是1,它應該等於allocationSize。

所以,好吧,所以添加「initialValue = 500」並更新我的DDL腳本爲「START 500」可以解決此問題,但現在我的編號從500開始,而不是從1開始。這是一個EclipseLink錯誤還是有我不理解的東西。我想要生成從1開始的序列,並將分配大小調整爲實體(本例中爲500)。我如何使用EclipseLink來做到這一點?

謝謝!

另一種方式來問這個是....這給出DDL:

CREATE SEQUENCE EMAIL_SEQ_GEN START 1 INCREMENT 500; 

什麼是註釋我的實體與EclipseLink的使用正確的方法是什麼?

如果我讓EclipseLink的生成我DDL那麼這樣的:

@GeneratedValue(strategy = GenerationType.AUTO, generator = "email-seq-gen") 
@SequenceGenerator(name="email-seq-gen", sequenceName="EMAIL_SEQ_GEN", initialValue=1, allocationSize=500) 

會產生這樣的:

CREATE SEQUENCE EMAIL_SEQ_GEN INCREMENT BY 500 START WITH 500; 

哪一種暗示,這是不可能創建一個DDL以「START WITH 1 「使用EclipseLink。

+0

如果你走另一個方向(讓EclipseLink從你的實體生成DDL),它會產生什麼? – DannyMo

+0

我編輯了原始文章以添加問題的答案。 –

回答

18

默認情況下,使用@SequenceGenerator註解的實體使用initialValue = 1和alocationSize = 50。

public @interface SequenceGenerator { 
    /** 
    * (Optional) The value from which the sequence object 
    * is to start generating. 
    */ 
    int initialValue() default 1; 

    /** 
    * (Optional) The amount to increment by when allocating 
    * sequence numbers from the sequence. 
    */ 
    int allocationSize() default 50; 
} 

「連續」,實體ID似乎是的EclipseLink用以下公式計算:

entityId = initialValue - allocationSize + INCREMENT_BY 

或使用DDL的情況下:

entityId = START_WITH - allocationSize + INCREMENT_BY 

再回到您的特定案例:


@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    allocationSize=500 
) // initialValue=1 (default) 

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 1 INCREMENT BY 500; 

產生

entityId = 1 - 500 + 1 = -500 // EclipseLink error 

@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    initialValue=1, 
    allocationSize=500) 

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 1 INCREMENT BY 500; 

產生

entityId = 1 - 500 + 1 = -500 // EclipseLink error 

@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    initialValue=500, 
    allocationSize=500 
) 

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 500 INCREMENT BY 500; 

產生

entityId = 500 - 500 + 500 = 500 // fine, but inappropriate 
entityId = 500 - 500 + 1000 = 1000 // incremented by 500 
entityId = 500 - 500 + 1500 = 1500 // incremented by 500 
... 

滿足您的要求應該使用下列內容:

@SequenceGenerator( 
    name="email-seq-gen", 
    sequenceName="EMAIL_SEQ_GEN", 
    allocationSize=500 
) // initialValue=1 (default) but 'START WITH'=500 

CREATE SEQUENCE EMAIL_SEQ_GEN START WITH 500 INCREMENT BY 1; 

產生

entityId = 500 - 500 + 1 = 1 
entityId = 500 - 500 + 2 = 2 
entityId = 500 - 500 + 3 = 3 
... 

現有的序列可以從下面的底層數據庫中刪除SQL command

DROP SEQUENCE email_seq_gen RESTRICT; 

我希望它有幫助。

+0

很高興知道如何刪除/刪除創建的序列。我嘗試了幾種方法,但都沒有工作。 – burseaner

+0

@burseaner:我添加了一個命令,用於刪除一個存在的序列。 – wypieprz

+1

用增量1創建序列是錯誤的。 EclipseLink每個分配批次只調用一次序列(在這種情況下,對於在同一事務中添加的每500個實體一次)。 因此增量必須等於500.是的,當分配批次小於500時,數字將被跳過,但這是您爲效率付出的代價,這是由於序列的調用較少。 要查看發生的錯誤,請添加兩個實體,然後終止Java程序,然後添加另一個實體。由於重複的ID,將發生java.sql.SQLIntegrityConstraintViolationException。 – bgh

2

你的序列應在500而不是1開始如果你從1開始,那麼第一個NEXTVAL只會給你1號,而不是500

設置它後否則調用NEXTVAL在序列中,因此它達到501.

錯誤是警告還是錯誤?如果你忽略它,它還能工作嗎?

+1

這有什麼意義?如果我編寫代碼池身份,我得到1,501,1001,等等。這也是我從Hibernate獲得的?如果EclipseLink沒有這種情況,並且(來自Google搜索),那麼很多人都遇到了這個問題,爲什麼他們不修正這個算法呢? –

+0

哦,這不是一個警告的錯誤。 –