なんてめちゃくちゃ...AUTO_INCREMENT MySQLの隠しシーケンスです。根本的な問題は、MySQL PKの挿入と返却を同時に行うことはできませんが、HibernateはINSERT中にこれを必要とします 新しいエンティティを作成します。
遭遇した問題:
- Hibernateが新しいエンティティを保存する場合、HibernateはIDを新しいEntityBeanに没頭して設定しようとします。したがって、hibernateは、hibernateが新しいタプルをテーブルに保存する前に、データベースが使用するIDを読み取る必要があります。
- データベースにアクセスするサーバーが複数ある場合は、hibernateのセッションファクトリに組み込みシーケンス(AUTO-INCREMENT)の使用を決定させるか、hibernateに決定(
GenerationType.AUTO)させる必要があります。 /GenerationType.IDENTITY)予約されたPKのオープン範囲がどれだけ大きいか(DBアーキテクトの仕事)。 (1つのデータベースに対して約20台のサーバーがあるため、よく使用されるテーブルでは、PK距離+100を使用します)。 1台のサーバーのみがデータベースにアクセスできる場合GenerationType.TABLE正しくなければなりません。
Hibernateは、max(*)+1を使用して自分で次のIDを計算する必要があります しかし:
- 2つのリクエストが
max(*)+1を要求した場合はどうなりますか 同時に/同じ結果で?右:最後のinsertの試み 失敗します。
したがって、テーブルLAST_IDSが必要です。 最後のTable-PKを格納するデータベース内。追加する場合は、次の手順を実行する必要があります。
- 読み取りに最適なトランザクションを開始します。
- SELECT MAX(address_id)FROM LAST_IDS
- 最大値をJava変数に格納します。例:$OldID。
- $ NewID =$ OldID + 1.(悲観的ロックでは+100)
- UPDATE LAST_IDS SET address_id =
$newIDWHERE address_id =$oldID? - 読み取り最適化トランザクションをコミットします。
- コミットが成功した場合は、
$newIDを保存しますsetID()へ 保存したいHibernateBeanで。 - 最後に、Hibernateにインサートを呼び出させます。
これが私が知っている唯一の方法です。
ところで:Hibernate-データベースがPostgreSQLのようなテーブル間の継承をサポートしている場合にのみ、エンティティは継承を使用します またはOracle 。