エンティティクラス

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

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

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

@Entity
public class Employee {
    ...
}

エンティティ クラスは他のエンティティクラスを継承できます。

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

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

注釈

Java 14 以降のバージョンでは、records@Entity アノテーションを付けられます。

@Entity
public record Employee(...) {
}

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

エンティティリスナー

エンティティ リスナーは、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 が SEQUENCE をサポートしているわけではありません。

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;

OriginalStates

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

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

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

@OriginalStates
Employee originalStates;

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

メソッドの定義

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

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

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