2013-08-27 13 views
13

私は頭がいっぱいです。 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; 

あまり休止状態では、私は次のように問題を持っていません。すべてが期待どおりに機能します。

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

だからもちろん、私は周りのGoogleとのEclipseLinkは初期値が1の場合は負の数を作成し、それがallocationSizeに等しくなければならないことについて何かを参照してください。私はEclipseLinkのに自分のプロバイダを切り替える場合は、私はこのエラーを取得します。

「initialValue = 500」を追加し、DDLスクリプトを「START 500」に更新するとこれが修正されますが、現在では番号が1ではなく500で開始されます。これは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) 

はこれを生成します:種類の「1で始まるとDDLを作成することは不可能であることを意味し

CREATE SEQUENCE EMAIL_SEQ_GEN INCREMENT BY 500 START WITH 500; 

"を使用しています。

+0

逆方向に進むと(エンティティから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 = START_WITH - allocationSize + INCREMENT_BY 

があなたの特定に戻っ:

entityId = initialValue - allocationSize + INCREMENT_BY 

またはDDLを使用した場合の

ケース:


@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は、アロケーション・バッチごとに1回だけこのシーケンスを呼び出します(この場合、同じトランザクションで追加された500個のエンティティごとに1回)。 したがって、増分は500に等しくなければなりません。割り当てバッチが500より小さい場合、数値はスキップされますが、それはシーケンスの呼び出し回数が少なくて済むので、効率的な料金です。 エラーを表示するには、2つのエンティティを追加してからJavaプログラムを終了し、別のエンティティを追加します。重複したIDのためにjava.sql.SQLIntegrityConstraintViolationExceptionが発生します。 – bgh

2

あなたの順序は、そうでなければ、それを設定した後シーケンス上のnextval呼び出して、あなたが1で起動した場合、最初のnextvalが唯一のあなたの代わりに500

の1つのIDを与えるません1. 500で始まっているので、必要があります501になる。

エラーは警告またはエラーですか?無視してもそれはまだ機能しますか?

+1

それはどうやって意味がありますか?アイデンティティをプールするコードを書くと、1、501、1001などが得られます。これは私がHibernateから得るものですか?これがEclipseLinkの場合ではなく、(グーグル・グーグルでは)多くの人がこの問題を抱えているように見えますが、なぜこのアルゴリズムを修正しないのですか? –

+0

ああ、警告ではなくエラーです。 –

関連する問題