PostgreSQLシーケンスの冬眠の使用は、シーケンステーブルに影響しません
-
28-09-2019 - |
質問
PostgreSQLシーケンスを使用して(注釈を介して)Hibernateを構成し、プライマリキーの値を生成しました ID 列次のような列:
@Id
@SequenceGenerator(name="pk_sequence",sequenceName="entity_id_seq")
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="pk_sequence")
@Column(name="id", unique=true, nullable=false)
public int getId() {
return this.id;
}
この構成で私が見ているのは、Hibernateがすでに割り当てられていることです ID 使用されているシーケンスのクエリは次のことを示していますが、持続する値は3000以上です。
database=# select last_value from entity_id_seq;
last_value
------------
69
(1行)
質問:
何か問題がありますか?
Hibernateはシーケンステーブルと同期する必要がありますか?
そうでない場合、最後に生成されたIDをどこに保存しますか?
ありがとうございました。
解決
同じ問題がありました。これは、冬眠のID割り当て戦略に関連しています。あなたが選ぶのはいつですか GenerationType.Sequence, 、Hibernateは、デフォルトで50のブロックでIDを割り当てるHilo戦略を使用します。したがって、明示的に設定できます 割り当て このような価値:
@Id
@SequenceGenerator(name="pk_sequence",sequenceName="entity_id_seq", allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="pk_sequence")
@Column(name="id", unique=true, nullable=false)
public int getId() {
return this.id;
}
しかし、私はまた、hilo戦略を使用するという意見を聞いたことがあります Allocationsize = 1 良い習慣ではありません。一部の人々は使用することをお勧めします GenerationType.auto 代わりに、データベース管理されたシーケンスを処理する必要がある場合
アップデート: 私はAllocationsize = 1で行くことになりました、そして、私が今期待するように物事は機能しているようです。私のアプリケーションは、とにかくIDのブロックを本当に必要としないので、 ymmv.
他のヒント
PostgresシーケンスにGenerationType.Sequenceを使用しないでください!
それは完全に直感に反していますが、冬眠の人々はこれを完全に台無しにしました。君 GenerationType.autoを使用する必要があります または冬眠する 破壊します DBを再起動/再構築する必要がある場合は、シーケンス。このコードがプロダクションビルドに入ることを許可することは、ほぼ犯罪的に過失ですが、Hibernateチームは、たとえば、左結合のポジションをチェックしてください)。
まず、使用している冬眠のバージョンを決定する必要があります。 Hibernate-Coreバージョンに関しては、3.2以降、特に注釈で定義されていることに関して、IDジェネレーターのより一貫したサポートが導入されました。見る http://in.relation.to/bloggers/new323hibernateidentidifiergenerators 議論のために。
次の3.6は、そのブログで議論されているジェネレーターがデフォルトの方法JPA-Annotationsが処理されるようにする設定( 'hibernate.id.new_generator_mappings')を導入しました。 Hibernateは、古いバージョンとの逆方向の互換性を維持する必要があるため、デフォルトで設定が誤っています。新しい動作が必要な場合(完全に推奨されています)、その設定をtrueに設定するだけです。
GenerationTypeの処理方法は、使用しているバージョンと 'hibernate.id.new_generator_mappings'を使用しているかどうかによって異なります。私はあなたが3.6+を使用していると仮定します(古いものはまあ、古いものであるため)。
- GenerationType.auto-> GenerationType.Sequenceとして扱われます
- GenerationType.Sequence-> org.hibernate.id.enhanced.Sequencestylegeneratorクラスのブログで議論されているマップ
- GenerationType.Table-> org.hibernate.id.enhanced.TableGeneratorクラスのブログで議論されているマップ
Postgresでは、これを行います。
@Id
@SequenceGenerator(name="pk_sequence",sequenceName="\"entity_id_seq\"")
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="\"pk_sequence\"")
@Column(name="\"id\"", unique=true)
private int id;
主に大文字の名前では、ポストグレスを理解し、テーブル、列、またはシーケンス名を見つけるために、逃げ出し引用符を渡す必要があります。