エンティティクラス

エンティティクラスはデータベースのテーブルまたはクエリの結果セットに対応します。

エンティティクラスの定義

次のコードスニペットは、エンティティクラスを定義する方法を示しています。

@Entity
public class Employee {
    //...
}

エンティティ クラスは別のエンティティ クラスから継承することができます。

次のコード スニペットは、他のエンティティ クラスを継承する方法を示しています。

@Entity
public class SkilledEmployee extends Employee {
    //...
}

注釈

records には @Entity を注釈できます。

@Entity
public record Employee(@Id Integer id, String name) {
}

この場合、@Entity の不変プロパティが false であっても、エンティティは immutable として認識されます。

エンティティリスナー

エンティティ リスナーは、Doma がINSERT、DELETE、UPDATEなどのデータベース変更ステートメントを発行する前または後に実行されます。

次のコードスニペットは、エンティティリスナーを定義する方法を示しています。

public class EmployeeEntityListener implements EntityListener<Employee> {
    // ...
}

エンティティ リスナーを使用するには、それを @Entity アノテーション 内の listener プロパティに指定します。

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

エンティティのサブクラスは、親のエンティティ リスナーを継承します。

命名規則

命名規約は次の間でマッピングを定義します。

  • データベーステーブルとJavaエンティティクラス

  • データベースのカラムとJavaのエンティティのフィールド

次のコードスニペットは、命名規則をエンティティに適用する方法を示しています。

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

@Table または @Column アノテーション内の name プロパティに値が明示的に指定された場合、命名規則はその要素に対して無視されます。

エンティティのサブクラスは、親の命名規則を継承します。

不変

エンティティクラスは不変にできます。

次のコード スニペットは、不変エンティティを定義する方法を示しています。

@Entity(immutable = true)
public class Employee {
    @Id
    final Integer id;
    final String name;
    @Version
    final Integer version;

    public Employee(Integer id, String name, Integer version) {
        this.id = id;
        this.name = name;
        this.version = version;
    }
    // ...
}

@Entity アノテーションの immutable プロパティは true に設定されている必要があります。すべての永続フィールドは final として宣言されなければなりません。

エンティティのサブクラスは、親の不変プロパティを継承します。

テーブル

@Table アノテーション を使用して、対応するテーブル名を指定できます。

@Entity
@Table(name = "EMP")
public class Employee {
    // ...
}

@Table アノテーションが指定されていない場合、テーブル名は [naming-convention` によって決定されます。

フィールドの定義

デフォルトでは、すべてのフィールドは永続的で、データベースまたは結果セットのカラムに対応します。

フィールドの型は次のいずれかである必要があります。

次のコード スニペットは、フィールドを定義する方法を示しています。

@Entity
public class Employee {
    // ...
    Integer employeeId;
}

カラム

カラム名を @Column アノテーションで指定できます。

@Column(name = "ENAME")
String employeeName;

INSERT または UPDATE ステートメントからフィールドを除外するには、@Column アノテーション内の insertable または updatable プロパティに false を設定します。

@Column(insertable = false, updatable = false)
String employeeName;

@Column アノテーションが指定されていない場合、カラム名は [naming-convention` によって決定されます。

注釈

フィールドタイプが 埋め込み可能クラス の場合、フィールドに @Column アノテーション を適用することはできません。

ID

データベースの主キーは @Id アノテーション で表されます。

@Id
Integer id;

複合主キーに対しては、複数のフィールドに @Id アノテーションを適用します。

@Id
Integer id;

@Id
Integer id2;

注釈

フィールドタイプが 埋め込み可能クラス の場合、フィールドに @Id アノテーションを適用することはできません。

IDの生成

@GeneratedValue アノテーション を使用して、ID 値を自動的に生成するように Doma に指示できます。

フィールドの型は次のいずれかである必要があります。

  • java.lang.Number のサブクラス

  • 値の型が java.lang.Number のサブクラスである ドメインクラス

  • 要素の型が上記のいずれかであるjava.util.Optional

  • OptionalInt

  • OptionalLong

  • OptionalDouble

  • 数値のプリミティブ型

注釈

生成された値は、フィールドが null または 0 未満の場合にのみフィールドに割り当てられます。プリミティブ型の 1 つをフィールド型として使用する場合は、フィールドを -1 などの 0 より小さい値で初期化してください。

IDENTITYによるID生成

RDBMSのIDENTITY機能を使用して値を生成するには、 @GeneratedValue アノテーションの strategy プロパティを GenerationType.IDENTITY に設定します:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Integer id;

まず、データベーススキーマでプライマリキーをIDENTITYとして定義する必要があります。

警告

すべてのRDBMSがIDENTITY関数をサポートしているわけではありません。

SEQUENCEによるID生成

RDBMSのSEQUENCEを使用して値を生成するには、@GeneratedValue アノテーションの strategy プロパティを GenerationType.SEQUENCE に設定します。そして、@SequenceGenerator アノテーションを使用します:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@SequenceGenerator(sequence = "EMPLOYEE_SEQ")
Integer id;

あらかじめデータベースにSEQUENCEを定義しておきます。名前、割り当てサイズ、初期サイズなどの SEQUENCE 定義は、@SequenceGenerator アノテーション 内のプロパティに対応する必要があります。

警告

すべてのRDBMSがSEQUENCESをサポートしているわけではありません。

TABLEによるID生成

RDBMSのTABLEを使用して値を生成するには、@GeneratedValue アノテーションの strategy プロパティを GenerationType.TABLE に設定します。そして、@TableGenerator アノテーションを使用します:

@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@TableGenerator(pkColumnValue = "EMPLOYEE_ID")
Integer id;

あらかじめデータベースにTABLEを定義しておきます。 TABLE の定義は、@TableGenerator アノテーション 内のプロパティに対応する必要があります。たとえば、DDL は次のようになります。

CREATE TABLE ID_GENERATOR(PK VARCHAR(20) NOT NULL PRIMARY KEY, VALUE INTEGER NOT NULL);

テーブル と カラム の名前は、@TableGenerator アノテーション 内のプロパティを使用して変更できます。

バージョン

楽観的排他制御のバージョンフィールドは、@Version アノテーションで表されます。

フィールドの型は次のいずれかである必要があります。

  • java.lang.Number のサブクラス

  • 値の型が java.lang.Number のサブクラスである ドメインクラス

  • 要素の型が上記のいずれかであるjava.util.Optional

  • OptionalInt

  • OptionalLong

  • OptionalDouble

  • 数値のプリミティブ型

@Version
Integer version;

注釈

フィールドタイプが 埋め込み可能クラスの場合、フィールドに @Version アノテーションを適用することはできません。

テナント ID

テナント IDのフィールドは、@TenantId アノテーション で表されます。このフィールドに対応するカラム は、UPDATEステートメント および DELETEステートメント の WHERE 句に含まれます。

@TenantId
String tenantId;

注釈

フィールドタイプが 埋め込み可能クラス の場合、フィールドに @TenantId アノテーションを適用することはできません。

Transient

エンティティに永続化したくないフィールドがある場合は、 @Transient アノテーションを付けることができます。

@Transient
List<String> nameList;

Association

エンティティ間の関連を表すフィールドには @Association アノテーションを使用します。

@Association
Address address;
@Association
List<Employee> assistants;

@Association で注釈されたフィールドはデータベースへ永続化されません。代わりに、この注釈はアグリゲートでエンティティリレーションシップを定義するために使用されます。

このアノテーションは、アグリゲート戦略と併用し、関連するエンティティが一貫性のある単位として扱われるようにする必要があります。詳細については、アグリゲート戦略 を参照してください。

OriginalStates

変更された値のみを UPDATE ステートメントに含めたい場合は、@OriginalStates の注釈を付けたフィールドを定義できます。フィールドには、データベースから取得した元の値を保持できます。

Doma は、アプリケーション内でどのフィールドが変更されたかを判断し、変更された値のみを UPDATE ステートメントに含めるために、これらの値を使用します。

次のコードスニペットは、OriginalStates を定義する方法を示しています。

@OriginalStates
Employee originalStates;

フィールドの型はエンティティのタイプと同じである必要があります。

メソッドの定義

メソッドの使用に制限はありません。

Employee エンティティクラスをインスタンス化し、そのインスタンスを使用します。

void doSomething() {
    Employee employee = new Employee();
    employee.setEmployeeId(1);
    employee.setEmployeeName("SMITH");
    employee.setSalary(new BigDecimal(1000));
}