web-dev-qa-db-ja.com

Hibernateはシーケンスの使用時に負のid値を生成します

次の定義を持つクラスがあります。

@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から開始して上昇)

なぜこれが起こる可能性がありますか?

33
Tomer

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プロパティを自動的に設定します。設定されているプロパティの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は自動的に有効にします。

33
jrm

新しい動作は次のとおりです。

AllocationSizeは、Hibernate用に予約されている主キー値の範囲です。また、デュアルからのseq.nextvalの選択は、休止状態がこの範囲の主キーを消費した後にのみ行われます。

したがって、mustallocationSize(Hibernate)とシーケンスincrement by(DB)の両方で同じ値を宣言します

allocationSize=500を明示的に設定する場合、例: Oracleで

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

そうしないと、主キーの衝突のために、DBから負の値または制約エラーが発生します。

アプリサーバーを再起動すると、割り当てられた最新のプライマリキーと再起動時に選択された「新たな」シーケンス番号の間の「ジャンプ」に気付くでしょう。

最終コメント:デフォルト値は50です。したがって、Hibernate側でallocationSizeを指定しない場合、DB側でmustを宣言するincrement by 50です。

68
skay

hibernate.id.new_generator_mappingspersistence.xmlfalseに設定することは、私の問題に対する解決策の最初の部分にすぎません。

問題を完全に解決するために、1@SequenceGeneratorallocationSizeを追加しました(これは省略していました)。

22
falsarella