なんてめちゃくちゃ...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 =
$newID
WHERE address_id =$oldID
? - 読み取り最適化トランザクションをコミットします。
- コミットが成功した場合は、
$newID
を保存しますsetID()
へ 保存したいHibernateBeanで。 - 最後に、Hibernateにインサートを呼び出させます。
これが私が知っている唯一の方法です。
ところで:Hibernate-データベースがPostgreSQL
のようなテーブル間の継承をサポートしている場合にのみ、エンティティは継承を使用します またはOracle
。