2011-01-24 13 views
1

私はいくつかのデータモデルのリファクタリングの後にいくつかのデータマイグレーションをしています。私はコンポジットプライマリキーを持つテーブルをいくつか取り、それをより大きなテーブルに結合して独自のプライマリキーを与えています。この時点で、古いテーブルデータを新しいテーブルにコピーし、AUTO_INCREMENTを使用してプライマリキーを割り当てるSQLを書きました。移行が完了したら、私はPKフィールドからAUTO_INCREMENTを削除します。だから、それはすべてグレイビーですが、問題は、次に利用可能なPKが何であるかを知るためにハイバネートシーケンスが必要なことです。私たちは一般にすべてのエンティティに対してTABLE戦略を使用しています。私は一貫性を保ち、将来のオブジェクトにAUTO_INCREMENTとIDENTITY戦略を使用しないようにしたいと思います。私は一時的に生成された "hibernate_sequences"テーブルの各行を新しく作成されたテーブルの最大IDに設定することを止めましたが、これは単に問題に対するバンドの修正です。また、次のIDがmax idよりもはるかに大きくなるように作成されます。私はHiLoのid割り当て機構を理解できないので、これは確かです。なぜ私がここに投稿しているのかということです。 Idをシーケンシャルにするためにこれを設定する方法はありますか?または、HiLo値を生成するコードはどこにありますか?シーケンシャルIDを確実にするために必要なものを計算できますか?mysqlで手動でハイバネーションシーケンスを設定するにはどうしたらいいですか?

答えて

0

使用org.hibernate.id.MultipleHiLoPerTableGenerator#が生成生成のためのソースコードを見ているだろう、私は私のバッチことを考え出しましたサイズが50だったので、max id/50 + 1を使用する私の目的のために、できるだけシーケンシャルに近づけるためにシーケンスにスローするのに使用可能な数を生成しました。

2

私が正しく理解していれば、問題はhibernateがあなたのためにシークレットIDを生成しないということです。しかし、それはどのようにハイ/ロージェネレータが動作し、私はあなたがそれを好まない理由を正確に理解していません。

基本的にHi/lowジェネレータは、HIGH値とLOW値を別々にサポートしています。 LOWが限界に達するとリセットされ、HIGHがインクリメントされます。結果キーは、HIGH値とLOW値を組み合わせたものです。例えば。キーはダブルワード、HIGHとLOWはワードとする。 HIGHは2バイト、LOWは2バイトのままにすることができます。

IDのジャンプは、LOWの最大値とHIGHの値の変更をトリガーするイベントの2つの要因によって異なります。 デフォルトでは、Hibernateでは、LOWの最大値はShort.MAX_VALUEで、各ジェネレータの初期化時にリセットされます。 HIGH値はテーブルから読み込まれ、各初期化時にインクリメントされ、LOWが上限に達するとインクリメントされます。これは、アプリケーションを再起動するたびに、IDにギャップがあることを意味します。

コードを見ると、max_loに値<を1つ使用すると、キーがhi値をインクリメントするだけで生成され、これはDBから読み取られるようです。おそらく、その行動:)

ようorg.hibernate.id.MultipleHiLoPerTableGenerator#は

+1

シーケンシャルPKを使用するには、挿入を実行するたびにDBをヒットする必要があります。 HiLoアルゴリズムは、あなたがPKのためにDBを照会するときに、1つのPKを取得する代わりに、あなたが使用するためにPKの全体の「ブロック」を予約するように設計されています。欠点は、予約されたPKのブロックが使用されない場合、PKに「穴」があることです。 DB内の他のテーブルがHiLoを問題なく使用していると述べました。挿入順は、PKの順番から現在取得しているDBに取り込むデータの一部ですか? –

+0

http://stackoverflow.com/questions/282099/whats-the-hi-lo-algorithm/282113#282113も参照してください。 –

+0

@binilシーケンシャルID生成の場合のdbアクセスについての言及をありがとう!それは私が忘れてしまった重要なことです。 – Stas

関連する問題