[Hibernate] OracleのSEQUENCEを利用した主キーの生成 | Archive Redo Blog

Archive Redo Blog

DBエンジニアのあれこれ備忘録

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メソッドを実行した時となっているようです。


これはおそらく、関連テーブルのレコードを同時に登録する場合に主キーの値が必要になるケースがあるからだろうと思われます。