5.1.3. class

5.1.3. class

class 要素を使って、永続クラスを宣言できます:

<class
        name="ClassName"
        table="tableName"
        discriminator-value="discriminator_value"
        mutable="true|false"
        schema="owner"
        catalog="catalog"
        proxy="ProxyInterface"
        dynamic-update="true|false"
        dynamic-insert="true|false"
        select-before-update="true|false"
        polymorphism="implicit|explicit"
        where="arbitrary sql where condition"
        persister="PersisterClass"
        batch-size="N"
        optimistic-lock="none|version|dirty|all"
        lazy="true|false"
        entity-name="EntityName"
        check="arbitrary sql check condition"
        rowid="rowid"
        subselect="SQL expression"
        abstract="true|false"
        node="element-name"
/>

name (オプション):永続クラス(またはインターフェース)の完全修飾 Java クラス名。もしこの属性が欠落している場合、 POJO ではないエンティティに対するマッピングとして扱われます。

table (オプション - デフォルトは修飾されていないクラス名):データベーステーブルの名前

discriminator-value (オプション - デフォルトはクラス名): ポリモーフィックな振る舞いに使われる個々のサブクラスを識別するための値。値は nullnot null のいずれかを取ります。

mutable (オプション、デフォルトは true ): そのクラスのインスタンスが更新可能(または不可能)であることを指定します。

schema (オプション): ルートの <hibernate-mapping> 要素で指定したスキーマ名をオーバーライドします。

catalog (オプション): ルートの <hibernate-mapping> 要素で指定したカタログ名をオーバーライドします。

proxy (オプション):遅延初期化プロキシに使うインターフェースを指定します。永続化するクラス名そのものを指定することも可能です。

dynamic-update (オプション、 デフォルトは false ):値が変更されたカラムだけを含む SQL の UPDATE 文を、実行時に生成することを指定します。

dynamic-insert (オプション, デフォルトは false ):値が null ではないカラムだけを含む SQL の INSERT 文を、実行時に生成することを指定します。

select-before-update (オプション、デフォルトは false): オブジェクトが変更されたのが確実でないならば、 Hibernate が SQL の UPDATE決して実行しない ことを指定します。ある特定の場合(実際的には、一時オブジェクトが update() を使い、新しいセッションと関連付けられた時だけ)、 UPDATE が実際に必要かどうかを決定するために、 Hibernate が余分な SQL の SELECT 文を実行することを意味します。

polymorphism (オプション、デフォルトでは implicit ): implicit(暗黙)かexplicit(明示)の、どちらのクエリポリモーフィズムを使うか決定します。

where (オプション): このクラスのオブジェクトを検索するときに使用する、任意の SQL の WHERE 条件を指定します。

persister (オプション):カスタム ClassPersister を指定します。

batch-size (オプション、デフォルトは 1 ): 識別子でこのクラスのインスタンスを復元するときの「バッチサイズ」を指定します。

optimistic-lock (オプション、デフォルトは version ): 楽観ロック戦略を決定します。

lazy (オプション): lazy="false" と設定することで、遅延フェッチができなくなります。

entity-name (オプション、デフォルトはクラス名): Hibernate3 ではクラスが複数回マッピングでき(場合によっては違うテーブルに対しても)、 Java レベルで Map や XML で表現されるエンティティマッピングが可能です。これらの場合、エンティティに対して任意の名前を、明示的に付けなくてはなりません。 詳しくは 項4.4. 「動的モデル」章 18. XML マッピング を参照してください。

check (オプション):自動的にスキーマを生成するために、複数行の check 制約を生成する SQL 式。

rowid (オプション): Hibernate は、それをサポートしているデータベースで ROWID と 呼ばれるものを使うことができます。例えば Oracle を使っているとき、このオプションに rowid を設定すれば、 Hiberante は update を高速化するために rowid という特別なカラムを使うことができます。 ROWID は詳細な実装であり、保存されたタプルの物理的な位置を表しています。

subselect (オプション):不変かつ読み取り専用であるエンティティをデータベースの副問合せ(subselect)にマッピングします。もし元のテーブルの代わりにビューを持ちたければ有用ですが、そうでないのなら有用ではありません。より詳しい情報は下記を参照してください。

abstract (オプション): <union-subclass> 階層内の抽象スーパークラスにマークするために使います。

永続クラスの名前にインターフェースを指定してもまったく問題ありません。そのときは <subclass> 要素を使って、そのインターフェースを実装するクラスを定義してください。 static な内部クラスでも永続化できます。そのときは標準形式、例えば eg.Foo$Bar を使ってクラス名を指定してください。

mutable="false" 指定をした不変クラスは、アプリケーションによる更新や削除が出来ないことがあります。これにより、 Hibernate がパフォーマンスを少し改善します。

オプションの proxy 属性により、クラスの永続インスタンスの遅延初期化が可能になります。 Hibernate は最初に、指定したインターフェースを実装した CGLIB プロキシを返します。実際の永続オブジェクトはプロキシのメソッドを呼び出すときにロードします。以下の「遅延初期化のためのプロキシ」を参照してください。

暗黙的 ポリモーフィズムとは、次の二つを意味しています。一つはクラスのインスタンスが、スーパークラスや実装したインターフェース、またそのクラスを指定するクエリによって返されることで、もう一つはそのクラスのサブクラスのインスタンスが、そのクラス自身を指定したクエリによって返されることです。また、 明示的 ポリモーフィズムとは、次の二つを意味しています。一つはクラスのインスタンスが、そのクラスを明示的に指定したクエリによってのみ返されることで、もう一つはクラスを指定したクエリが、 <class> 要素の中で <subclass><joined-subclass> とマッピングされているサブクラスのインスタンスだけを返すことです。ほとんどの用途ではデフォルトの polymorphism="implicit" が適切です。明示的なポリモーフィズムは、2つの違ったクラスが同じテーブルにマッピングされているときに有用です (これによってテーブルカラムのサブセットを含む、「軽量な」クラスが可能になります)。

persister 属性を指定することで、クラスの永続化戦略をカスタマイズできます。例えば org.hibernate.persister.EntityPersister 自身のサブクラスを指定したり、また例えばストアドプロシージャコール、フラットファイルへシリアライズ、 LDAP などを通した永続性を実装する org.hibernate.persister.ClassPersister インターフェースの完全に新しい実装を提供できます。簡単な例として org.hibernate.test.CustomPersister を参照してください(これは Hashtable の「永続化」です)。

dynamic-updatedynamic-insert の設定はサブクラスに継承されません。そのため <subclass><joined-subclass> 要素を指定することも出来ます。これらの設定はパフォーマンスを向上させる事もありますが、落とすこともありますので、慎重に使用してください。

select-before-update の使用は通常パフォーマンスを落とします。もし Session へ分離インスタンスのグラフを再追加するなら、データベース更新のトリガを不必要に呼び出すのを避けるという点で、非常に有用です。

dynamic-update を有効にすれば、楽観ロック戦略を選ぶことになります:

Hibernate で楽観的ロック戦略を使うなら、バージョン/タイムスタンプカラムを使うことを 非常に 強くお勧めします。楽観的ロックはパフォーマンスの観点からも最適であり、さらに分離インスタンスへの修正 (つまり Session.marge() が使われるとき) を正確に扱うことのできる唯一の戦略でもあります。

Hibernate のマッピングにとってビューと普通のテーブルの間に違いはなく、データベースレベルでは透過的です(ただしビューを完全にはサポートしていない DBMS もあります。特に、更新のあるビューに対してはそうです)。ビューを使いたくても、データベースで作成できないことがあります(例えば、レガシースキーマの場合)。この場合には、不変かつ読み取り専用のエンティティに与えられた SQL の副問合せ文をマップできます:

<class name="Summary">
    <subselect>
        select item.name, max(bid.amount), count(*)
        from item
        join bid on bid.item_id = item.id
        group by item.name
    </subselect>
    <synchronize table="item"/>
    <synchronize table="bid"/>
    <id name="name"/>
    ...
</class>

テーブルをこのエンティティと同期するように定義してください。オートフラッシュが確実に起こるように、また導出エンティティに対するクエリが古いデータを返さないようにするためです。 <subselect> は属性とネストしたマッピング属性のどちらでも利用できます。