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


102

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

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

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

また、転換点を探しています。

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

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

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

回答:


92

APIのドキュメントは、この上で非常に明確です。

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

インクリメント

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

身元

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

シーケンス

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

ヒロ

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

seqhilo

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

UUID

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

GUID

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

ネイティブ

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

割り当てられた

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

選択する

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

外国人

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

シーケンスID

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

同時ユーザーが少ない単純なアプリケーションを構築している場合は、増分、ID、HILOなどを使用できます。これらは設定が簡単で、DB内でのコーディングはあまり必要ありませんでした。

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

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


ご回答ありがとうございます。私はすでにドキュメントを見てきました。しかし、なぜhiloやseqhiloなどを使用するのかを探しています。私たちはいつその選択をしますか?selectのユースケースは何ですか。

シーケンスやGUIDのように単純なものがある場合、開発者が他の方法を選択する必要があるのは何ですか。

1
回答を更新しました。実際には、増分、アイデンティティ、ヒロなどが単純です。ただし、エンタープライズアプリケーションには適していません。すべてのオプションを維持することは問題ではありませんが、必ずあなたに最適なオプションを使用してください!
ManuPK 2012

うん。これまでのところ、賛成または賛成の特権はありませんでした。

詳細については、時間をお持ちの場合はお知らせください。

45

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

  • 自分で識別子を生成できます。その場合、割り当てられた識別子を使用できます。
  • @GeneratedValueアノテーションを使用すると、HibernateがIDを割り当てます。

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

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

  • 身元
  • シーケンス
  • テーブル

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

SEQUENCEは、特にpooledやpooled-loなどの識別子オプティマイザーで使用する場合に推奨されるオプションです。

TABLEは別のトランザクションを使用して識別子と行レベルのロックをフェッチするため、スケーリングが不十分であるため、いかなる場合でも避けてください


20


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

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

少し外れたトピックですが、アプリケーション間で(APIを介して)キーを共有するという、見落とされがちなポイントを上げる良いチャンスです。個人的には常に代理キーを好んでおり、オブジェクトを他のシステムと通信する必要がある場合は、(代理キーであっても)キーを公開しません。追加の「外部キー」を使用します。コンサルタントとして、オブジェクトキーを使用した「優れた」システム統合(「それがあればすぐに使用できる」アプローチ)を2回以上見たことがあります。内部キーを公開するシステムでの深い移行が必要な種類。キーを公開することは、コードの基本的な側面を外部の制約に公開することを意味します。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.