エンティティクラス

Entity(エンティティ)は、データベースのテーブルやクエリの結果セットに対応します。

このページで説明するアノテーションはすべてorg.seasar.domaパッケージに属します。

エンティティクラスは @Entityが注釈されたクラスとして定義します。 クラスはトップレベルのクラスでなければいけません(他のクラスやインタフェースにネストされていてはいけません)。 エンティティクラスは 非privateなデフォルトコンストラクタ(引数なしのコンストラクタ)を持たなければいけません。

エンティティがデータベースに対し挿入、更新、削除される直前/直後に処理を実行したい場合、 listener 要素に org.seasar.doma.jdbc.entity.EntityListener の実装クラスを指定できます。

@Entity(listener = EmployeeEntityListener.class) public class Employee { ... }

listener 要素に何も指定しない場合、エンティティクラスが他のエンティティクラスを継承しているかどうかで採用する設定が変わります。

  • 継承している場合、親エンティティクラスの設定を引き継ぎます
  • 継承していない場合、何も行いません(org.seasar.doma.jdbc.entity.NullEntityListener が使用されます)

EntityListenerは、preDeletepreInsertpreUpdatepostDeletepostInsertpostUpdateの6つのメソッドをもったインタフェースです。

preDelete
@Delete、または@BatchDeleteが注釈されたDaoメソッドでパラメータにエンティティが含まれる場合、削除処理の直前に呼び出されます。 ただし、使用するエンティティクラスにエンティティリスナーが指定されている必要があります。
preInsert
@Insert、または@BatchInsertが注釈されたDaoメソッドでパラメータにエンティティが含まれる場合、挿入処理の直前に呼び出されます。 ただし、使用するエンティティクラスにエンティティリスナーが指定されている必要があります。
preUpdate
@Update、または@BatchUpdateが注釈されたDaoメソッドでパラメータにエンティティが含まれる場合、更新処理の直前に呼び出されます。 ただし、使用するエンティティクラスにエンティティリスナーが指定されている必要があります。
postDelete
@Delete、または@BatchDeleteが注釈されたDaoメソッドでパラメータにエンティティが含まれる場合、削除処理の直後に呼び出されます。 ただし、使用するエンティティクラスにエンティティリスナーが指定されている必要があります。
postInsert
@Insert、または@BatchInsertが注釈されたDaoメソッドでパラメータにエンティティが含まれる場合、挿入処理の直後に呼び出されます。 ただし、使用するエンティティクラスにエンティティリスナーが指定されている必要があります。
postUpdate
@Update、または@BatchUpdateが注釈されたDaoメソッドでパラメータにエンティティが含まれる場合、更新処理の直後に呼び出されます。 ただし、使用するエンティティクラスにエンティティリスナーが指定されている必要があります。

EntityListenerは次のように実装できます。

{ @Override public void preDelete(Employee entity, PreDeleteContext context) { ... } @Override public void preInsert(Employee entity, PreInsertContext context) { ... } @Override public void preUpdate(Employee entity, PreUpdateContext context) { ... } @Override public void postDelete(Employee entity, PostDeleteContext context) { ... } @Override public void postInsert(Employee entity, PostInsertContext context) { ... } @Override public void postUpdate(Employee entity, PostUpdateContext context) { ... } }]]>

EntityListenerの各メソッドの2番目のパラメータは挿入、更新、削除が行われた場合のコンテキスト情報です。 このコンテキスト情報には、エンティティのメタクラス、Daoのメソッド、Daoの設定が含まれます。 たとえば、Daoのメソッドに独自のアノテーションをつけておくと、そのアノテーションの有無を見て特定のプロパティを更新するといったことが可能です。

EntityListenerの実装クラスはpublicなデフォルトコンストラクタ(引数なしのコンストラクタ)を持たねばいけません。

エンティティに対応するテーブル名やプロパティに対応するカラム名を解決するためのネーミング規約を変更したい場合、 naming 要素に org.seasar.doma.jdbc.entity.NamingType の列挙型を指定できます。

@Entity(naming = NamingType.SNAKE_UPPER_CASE) public class EmployeeInfo { ... }

naming 要素に何も指定しない場合、エンティティクラスが他のエンティティクラスを継承しているかどうかで採用する設定が変わります。

  • 継承している場合、親エンティティクラスの設定を引き継ぎます
  • 継承していない場合、何も行いません(org.seasar.doma.jdbc.entity.NamingType.NONE が使用されます)

NamingType.SNAKE_UPPER_CASEは、エンティティ名やプロパティ名をスネークケース(アンダースコア区切り)の大文字に変換します。この例の場合、テーブル名はEMPLOYEE_INFOになります。

naming要素に何も指定しない場合、デフォルトでは、テーブル名にはエンティティクラスの単純名、カラム名にはプロパティ名が使用されます。

ネーミング規約は、@Table@Columname要素が指定されない場合のみ使用されます。 @Table@Columname要素が指定された場合は、name要素に指定した値が使用され、ネーミング規約は適用されません。

NamingTypeには次の列挙定数があります。

列挙定数説明
NONE何も行いません。
SNAKE_UPPER_CASEキャメルケースをスネークケース(アンダースコア区切り)の大文字に変換します。
SNAKE_LOWER_CASEキャメルケースをスネークケース(アンダースコア区切り)の小文字に変換します。
UPPER_CASE大文字に変換します。
LOWER_CASE小文字に変換します。

エンティティに対応するテーブル情報を指定するには、 @Table を使用します。

name要素でテーブル名を指定できます。

catalog要素や schema要素 でカタログやスキーマを指定できます。

@Tableを使用しない、もしくは @Tablename要素を使用しない場合、 テーブル名は、ネーミング規約により解決されます。

任意のクラスを継承できます。

ただし、親クラスのフィールドが永続フィールドとみなされたりDomaのアノテーションが解釈されたりするのは、親クラスが@Entityで注釈されている場合だけです。

永続的なフィールドは、テーブルや結果セットのカラムに対応します。

フィールドの型は、基本型もしくはドメインクラスでなければいけません。

カラム

プロパティに対応するカラム情報を指定するには、@Columnを使用します。

name要素でカラム名を指定できます。

insertable要素や updatable要素 で挿入や更新の対象とするかどうかを指定できます。

@Columnを使用しない、もしくは@Columnname要素を使用しない場合、 カラム名は、ネーミング規約により解決されます。

識別子

識別子(主キー)であることを指定するには、@Idを使います。

複合主キーの場合は @Id を複数指定します。

識別子を自動生成する場合は、@GeneratedValueを使用し、 生成方法をstrategy要素に指定します。 このアノテーションが注釈されるフィールドの型は数値のプリミティブ型、 もしくはNumberのサブタイプでなければいけません。

strategy 要素に指定できる方法は、次の3つです。

GenerationType.IDENTITY

データベースのIDENTITY自動生成機能を利用する方法です。RDBMSによってはサポートされていません。 フィールドに対応するカラムの定義でIDENTITY自動生成を有効にしておく必要があります。

GenerationType.SEQUENCE

データベースのシーケンスを利用する方法です。RDBMSによってはサポートされていません。

GenerationType.SEQUENCEを使用するには、 @SequenceGeneratorを併記します。 @SequenceGeneratorでは、シーケンスの名前、割り当てサイズ、初期値等を設定できます。 データベースにあらかじめシーケンスを定義しておく必要がありますが、その定義は@SequenceGeneratorの定義とあわせておく必要があります。

GenerationType.TABLE

生成される識別子をテーブルで管理する方法です。すべてのRDBMSで利用できます。

GenerationType.TABLEを使用するには、 @TableGeneratorを併記します。 @TableGeneratorでは、テーブル名、割り当てサイズ、初期値等を設定できます。 データベースにあらかじめテーブルを定義しておく必要がありますが、その定義は@TableGeneratorの定義とあわせておく必要があります。 デフォルトでは、「ID_GENERATOR」という名前のテーブルに、文字列型の「PK」と数値型の「VALUE」という2つのカラムが定義されているものとして動作します(「PK」カラムが主キーです)。 「PK」カラムにはエンティティクラスごとの一意な名前、「VALUE」カラムには識別子の値が格納されます。 テーブルには、エンティティクラスごとのレコードをあらかじめ登録しておく必要があります。

@TableGeneratorpkColumnValue要素には、 識別子を管理するテーブル(デフォルトでは、「ID_GENERATOR」という名前のテーブル)の主キーの値を指定します。

バージョン

楽観的排他制御用のバージョンは@Versionを注釈して示します。

フィールドの型は数値のプリミティブ型 もしくはNumberのサブタイプでなければいけません。

非永続的なフィールドは、テーブルや結果セットのカラムに対応しません。

@Transientを注釈して示します。 フィールドの型や可視性に制限はありません。

@Transient List<String> nameList;

取得時の状態とは、エンティティがDaoから取得されときの全プロパティの値です。 取得時の状態を保持しておくことで、Daoインタフェースの@Updateが注釈されたメソッドを介して更新処理を実行する際、 UPDATE文のSET句に変更したフィールドのみを含めるようにすることが可能です。 取得時の状態を管理するフィールドは、テーブルや結果セットのカラムに対応しません。

@OriginalStatesを注釈して示します。 フィールドの型はフィールドが属するエンティティクラスと同じ型でなければいけません。 @OriginalStatesが注釈されたフィールドはアプリケーションで初期化したりアクセスしたりしてはいけません。

@OriginalStatesが注釈されたフィールドを持つエンティティの利用法は次のとおりです。

この例では、UPDATE文のSET句にAGEカラムだけが含まれます。

メソッドの定義に制限はありません。 フィールドの可視性をprotectedやパッケージプライベートにしてpublicなメソッド経由でアクセスすることも、 メソッドを一切使用せずpublicフィールドに直接アクセスすることもどちらもサポートされています。

インスタンス化して使用します。

エンティティはテーブルに1対1で対応させなければいけないわけではありません。 たとえば、EMPLOYEEテーブルとDEPARTMENTテーブルを結合した結果もエンティティにマッピングできます。 そのエンティティクラスをEmpDeptDtoとした場合のエンティティクラスの定義とDaoインタフェースの定義は次のとおりです。