web-dev-qa-db-ja.com

JPAおよびHibernateを使用する場合のID生成戦略の選択方法

HibernateリファレンスガイドのID生成セクションと「HibernateでのJavaの永続化」を実行していました

HibernateとJPAを組み合わせて使用​​できるオプションはかなりあります。

特定のID生成戦略を選択する方法に関するドキュメントを探していました。

転換点も探しています。

たとえば、ヒロ戦略は競合を減らすことが期待されています。この選択にはトレードオフが必要だと思います。

トレードオフについて教育を受けたいです。

利用可能な文献はありますか?

99
user1317764

API Doc はこれについて非常に明確です。

すべてのジェネレーターは、インターフェースorg.hibernate.id.IdentifierGeneratorを実装します。これは非常にシンプルなインターフェースです。一部のアプリケーションは、独自の特殊な実装を提供することを選択できますが、Hibernateはさまざまな組み込み実装を提供します。組み込みジェネレーターのショートカット名は次のとおりです。

インクリメント

他のプロセスが同じテーブルにデータを挿入していない場合にのみ一意であるlong、short、またはint型の識別子を生成します。クラスターでは使用しないでください。

アイデンティティ

dB2、MySQL、MS SQL Server、Sybase、HypersonicSQLのID列をサポートします。返される識別子は、long、short、またはint型です。

sequence

dB2、PostgreSQL、Oracle、SAP DB、McKoiのシーケンスまたはInterbaseのジェネレーターを使用します。返される識別子は、long、short、またはint型です。

hilo

hi/loアルゴリズムを使用して、テーブル、列(デフォルトではhibernate_unique_keyとnext_hiのそれぞれ)をhi値のソースとして指定し、long、short、またはint型の識別子を効率的に生成します。 hi/loアルゴリズムは、特定のデータベースに対してのみ一意の識別子を生成します。

seqhilo

hi/loアルゴリズムを使用して、名前付きデータベースシーケンスを指定して、long、short、またはint型の識別子を効率的に生成します。

uuid

128ビットUUIDアルゴリズムを使用して、ネットワーク内で一意のタイプ文字列の識別子を生成します(IPアドレスが使用されます)。 UUIDは、32桁の16進数の文字列としてエンコードされます。

guid

mS SQL ServerおよびMySQLでデータベース生成のGUID文字列を使用します。

native

基になるデータベースの機能に応じて、ID、シーケンス、またはhiloを選択します。

assigned

save()が呼び出される前に、アプリケーションがオブジェクトに識別子を割り当てることができます。要素が指定されていない場合、これがデフォルトの戦略です。

select

一意のキーで行を選択し、主キーの値を取得することにより、データベーストリガーによって割り当てられた主キーを取得します。

foreign

別の関連オブジェクトの識別子を使用します。通常、主キーの関連付けと組み合わせて使用​​されます。

sequence-identity

実際の値生成にデータベースシーケンスを利用し、これをJDBC3 getGeneratedKeysと組み合わせて、挿入ステートメント実行の一部として生成された識別子値を返す特殊なシーケンス生成戦略。この戦略は、JDK 1.4を対象としたOracle 10gドライバーでのみサポートされています。これらの挿入ステートメントに対するコメントは、Oracleドライバーのバグのため無効になっています。

同時ユーザーがあまり多くない単純なアプリケーションを構築している場合は、increment、identity、hiloなどを選択できます。これらは簡単に構成して実行できます。データベース内でのコーディングはあまり必要ありません。

データベースに応じて、sequenceまたはguidを選択する必要があります。 idの生成はデータベース内で行われるため、これらは安全で優れています。

更新:最近、プリミティブ型(int)の代わりにwarapper型(Integer)を使用することで修正されたidendityの問題がありました。

89
ManuPK

基本的に、2つの主要な選択肢があります。

  • 識別子は自分で生成できます。その場合、 割り当てられた識別子 を使用できます。
  • @GeneratedValue注釈を使用すると、Hibernateが識別子を割り当てます。

生成された識別子には、2つのオプションがあります。

数値識別子の場合 つのオプションがあります

  • 身元
  • シーケンス

IDENTITYは、 JDBCバッチ更新を無効にする であるため、SEQUENCE(MySQLなど)を使用できない場合にのみ適切な選択です。

SEQUENCEは、特に pooledまたはpooled-lo のような識別子オプティマイザーと併用する場合に推奨されるオプションです。

TABLEはどんな犠牲を払っても回避されます 識別子と行レベルのロックを取得するために個別のトランザクションを使用するため、スケーラビリティが不十分です。

43
Vlad Mihalcea


しばらく前に、Hibernateキージェネレータに関する詳細な記事を書きました: http://blog.eyallupu.com/2011/01/hibernatejpa-identity-generators.html

正しいジェネレーターを選択するのは複雑な作業ですが、できるだけ早く正しく実行することは重要です。移行が遅れると悪夢になる可能性があります。

ちょっとしたトピックですが、アプリケーション間でキーを共有している(APIを介して)通常見過ごされがちなポイントを上げる良いチャンスです。個人的には常にサロゲートキーを好み、オブジェクトを他のシステムと通信する必要がある場合、キーを公開しません(サロゲートキーであっても)–追加の「外部キー」を使用します。コンサルタントとして、私はオブジェクトキーを使用した「素晴らしい」システム統合を複数回見てきました(「それはそこにあるのでそれを使用しましょう」アプローチ)、1年または2年後に、一方がキー範囲または内部キーを公開するシステムでの深い移行が必要な種類。キーを公開するということは、コードの基本的な側面を外部の制約にさらすことを意味します。

20
Eyal Lupu

この講義は非常に貴重だと思います https://vimeo.com/190275665 、ポイント3ではこれらのジェネレーターを要約し、各ジェネレーターを使用する際のパフォーマンス分析とガイドラインを示します。

2
Adelin