Oracleシーケンスを使用するようにhibernateを構成しました。シーケンスはcache = 20、increment = 1で作成されます。
すべてが正常に動作し、休止状態の永続的なエンティティです。 id値が奇妙です:50,51 .... 76,201,202 ... 209,1008,1009,5129,5130 ....
シーケンス値を要求すると(デュアルからhibernate_sequence.nextvalを選択)、2、3、4などの値が得られます。
Hibernate sql debugをオンにすると、「select hibernate_sequence.nextval from dual」が時々呼び出されますが、hibernateによってIDに割り当てられた番号がシーケンスをリレーしません。
@Id
@Column(name = "ID", insertable = false, updatable = false)
@SequenceGenerator(name = "SequenceIdGenerator", sequenceName = "HIBERNATE_SEQUENCE")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SequenceIdGenerator")
private Long id;
これは、SequenceGeneratorが実際にはシーケンスジェネレータではないためです。シーケンスハイロージェネレーターです。つまり、最初に呼び出されたときに、シーケンスから次の値(たとえば6)を取得し、この値に50を掛けて結果(300)を返します。次に呼び出されると、301に戻り(シーケンスに移動せずに)、349に到達するまで繰り返されます。次に、シーケンスに次の値を要求し、7を取得します。これに50を掛けると350になります。Myアルゴリズムの説明は1つずれる可能性がありますが、アイデアは理解できます。
したがって、アプリケーションを停止して開始すると、ギャップが生じます。ただし、50世代に1回だけデータベース呼び出しを行うため、純粋なシーケンスジェネレーターよりも効率的です。
http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#mapping-declaration-id-enhanced-optimizers および http:/詳細は/docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#mapping-declaration-id-generator をご覧ください。
あなたの質問は、データベースのID列の値が自然なシーケンスではないことですが、なぜギャップが生じているのでしょうか。
背景のビット:
select HIBERNATE_SEQUENCE.nextval from DUAL
を呼び出すたびに、シーケンスの値が増加します。たとえば、次のシナリオを考えます。
IDジェネレーターとしてHIBERNATE_SEQUENCEを使用して、2つのエンティティEntity1とEntity2があります。
select HIBERNATE_SEQUENCE.nextval from DUAL
を実行します(104を返します)したがって、最後には次のようになります。
ギャップを説明します。
編集:
@SequenceGeneratorがSequenceGenerator
ではなくSequenceHiLoGenerator
を使用するように設定されていたとしても(JB Nizetが指摘したように、ギャップについてはより適切な説明だと思います)、生成されるIDのギャップシーケンスはよくあることです。
CREATE SEQUENCE SEQ_SEQUENCENAME INCREMENT BY 1 START WITH 1 MINVALUE 1;
grant all on SEQ_SEQUENCENAME to public;
@Id
@Column(name = "ID", unique = true, nullable = false)
@SequenceGenerator(name = "SequenceIdGenerator", sequenceName = "SEQ_SEQUENCENAME")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SequenceIdGenerator")
private int Id;