HibernateにはRDBMSの機能やアルゴリズムを利用して主キーを生成する機能があります。
主キーの生成方法は10種類ほど選択できるようになっていますが、よく使われるであろう生成方法は以下の通りとなっています。
identity | SQL ServerなどでサポートされているIDENTITY属性を利用して主キーを生成する。 |
sequence | OracleなどでサポートされているSEQUENCEを利用して主キーを生成する。 |
hilo | hi/loアルゴリズムに基づいてIDを生成する。(主キー生成用のテーブルを使用する) |
native | identity、sequenceのうち、RDBMSがサポートしている方を使用する。どちらも利用できない場合はhiloとなる。 |
assigned | ユーザーが明示的に主キーを設定する。 |
上記の生成方法は、使用するRDBMSやアプリケーションの特性を考慮して選択することになりますが、RDBMSにOracleを使用する場合は"sequence"を使うケースが多いのではないでしょうか。
ということで、OracleのSEQUENCEを使って主キーを生成する方法を以下にまとめます。
主キーの生成方法の指定
主キーの生成方法はマッピングファイルの例えば、sequenceを指定する場合は以下のようになります。
<id name="id" type="java.lang.Integer" column="ID" > <generator class="sequence"/> </id>
ただし、この設定の場合、データベース全体で一意な主キーが生成されるということになります。
つまり、他のテーブルで同じように設定している場合、テーブルをまたいで一意な主キーが生成されることになります。
例えば、ともに"sequence"を設定したAとBという2つのテーブルがあり、両方のテーブルに交互にレコードを登録した場合、Aのレコードの主キーが1、3、5、Bのレコードの主キーが2、4、6という風になります。
テーブルごとに一意な主キーを生成したい場合は、<param>にSEQUENCEの名称を設定する必要があります。
例えば、SQ_PRODUCTというSEQUENCEを使って主キーを生成したい場合は以下のようになります。
<generator class="sequence"> <param name="sequence">SQ_PRODUCT</param> </generator>
Middlegenを使ったボトムアップアプローチでのIDの生成方法の指定
あらかじめテーブルとSEQUENCEが用意されており、そこからMiddlegenを使ってマッピングファイルを生成する場合、Middlegenが基本的なマッピングを行ってくれますが、主キーの生成方法についてはMiddlegenでは判断できないため、デフォルトでは"assigned"となります。
これを"sequence"に変える場合は、MiddlegenのGUIのテーブルのプロパティの設定画面で[主キーの生成方法]に”SEQUENCE”を選択し、その右のテキストボックスに使用するSEQUENCEの名称を入力しする必要があります。
主キーが生成されるタイミング
主キーの生成方法を指定した場合、Hibernateを使用して主キーを設定せずにレコードを登録すると自動的に主キーが生成されます。
間違って主キーをセットしてしまったとしても無視されて主キーが生成されます。
主キーが生成されるタイミングはsaveメソッドを実行した時点となっています。
Hibernateでは登録・更新・削除のSQLが実行されるのはトランザクションのコミット時ですが、主キーの生成に限ってはsaveメソッドを実行した時となっているようです。
これはおそらく、関連テーブルのレコードを同時に登録する場合に主キーの値が必要になるケースがあるからだろうと思われます。