永続化エンティティ

CrudRepository.save(…) メソッドを使用して、集約を保存できます。集約が新しい場合、集約ルートの挿入が発生し、その後に直接または間接的に参照されるすべてのエンティティの挿入ステートメントが続きます。

集約ルートが新規ではない場合、すべての参照エンティティが削除され、集約ルートが更新され、すべての参照エンティティが再度挿入されます。インスタンスが新しいかどうかは、インスタンスの状態の一部であることに注意してください。

このアプローチには、明らかな欠点がいくつかあります。参照されたエンティティのうち実際に変更されたものがわずかしかない場合、削除と挿入は無駄です。このプロセスは改善される可能性があり、おそらく改善される予定ですが、Spring Data JDBC が提供できるものには特定の制限があります。集約の以前の状態はわかりません。そのため、更新プロセスは常にデータベースで見つかったものをすべて取得し、save メソッドに渡されたエンティティの状態に変換する必要があります。

詳細については、エンティティ状態の検出も参照してください。

集約のロード

Spring Data JDBC は、集約をロードする方法を 2 つ提供します。

  1. 従来のバージョン 3.2 より前のバージョンの唯一の方法は非常に簡単です。クエリが CrudRepository メソッド、派生クエリ、アノテーション付きクエリに基づいている場合、各クエリは独立して集約ルートをロードします。集約ルートが他のエンティティを参照する場合、別のステートメントでロードされます。

  2. Spring Data JDBC 3.2 では、単一クエリのロードを使用できます。これにより、単一の SQL クエリで任意の数の集約を完全にロードできます。これは、特に多くのエンティティで構成される複雑な集約の場合、大幅に効率的になるはずです。

    現在、単一クエリの読み込みはさまざまな方法で制限されています。

    1. 集約にはネストされたコレクションがあってはなりません。これには Map が含まれます。将来的にはこの制約を取り除く予定です。

    2. 集約では、AggregateReference または埋め込みエンティティを使用してはなりません。将来的にはこの制約を取り除く予定です。

    3. データベース言語はそれをサポートする必要があります。Spring Data JDBC が提供するダイアレクトのうち、H2 と HSQL を除くすべてがこれをサポートしています。H2 と HSQL は分析関数 (別名ウィンドウ関数) をサポートしていません。

    4. これは CrudRepository の find メソッドに対してのみ機能し、派生クエリやアノテーション付きクエリに対しては機能しません。将来的にはこの制約を取り除く予定です。

    5. 単一クエリの読み込みは、setSingleQueryLoadingEnabled(true) を呼び出して、JdbcMappingContext で有効にする必要があります。

いずれかの条件が満たされない場合、Spring Data JDBC は集約をロードするデフォルトのアプローチに戻ります。

単一クエリの読み込みは実験的であると考えられます。それがどのように機能するかについてのフィードバックをお待ちしております。
シングルクエリロードは SQL と略すこともできますが、構造化クエリ言語との混同がほぼ確実であるため、そうすることは強くお勧めしません。

ID 生成

Spring Data は、識別子プロパティを使用してエンティティを識別します。エンティティの ID には、Spring Data の @Id (Javadoc) アノテーションを付ける必要があります。

データベースに ID 列の自動インクリメント列がある場合、生成された値は、データベースに挿入された後にエンティティに設定されます。

Spring Data は、エンティティが新しく、識別子の値がデフォルトで初期値になっている場合、識別子の列の値を挿入しようとはしません。これは、プリミティブ型の場合は 0 であり、識別子プロパティが Long などの数値ラッパー型を使用している場合は null です。

エンティティ状態の検出では、エンティティが新しいかどうか、データベースに存在すると予想されるかどうかを検出する戦略について詳しく説明します。

重要な制約の 1 つは、エンティティを保存した後、そのエンティティが新しいものであってはならないことです。エンティティが新しいかどうかは、エンティティの状態の一部であることに注意してください。自動インクリメント列では、ID 列の値を使用して Spring Data によって ID が設定されるため、これは自動的に行われます。

楽観的ロック

Spring Data は、集約ルート上で @Version (Javadoc) のアノテーションが付けられた数値属性を使用してオプティミスティックロックをサポートします。Spring Data がそのようなバージョン属性を持つ集約を保存するときは常に、次の 2 つのことが起こります。

  • 集約ルートの更新ステートメントには、データベースに格納されているバージョンが実際に変更されていないことを確認する where 句が含まれます。

  • そうでない場合は、OptimisticLockingFailureException がスローされます。

また、エンティティとデータベースの両方でバージョン属性が増加するため、同時アクションは変更を認識し、上記で説明したように該当する場合は OptimisticLockingFailureException をスローします。

このプロセスは、新しい集合体の挿入にも適用されます。null または 0 バージョンは新しいインスタンスを示し、その後、増加したインスタンスはインスタンスを新規ではないものとしてマークします。UUID が使用されます。

削除中にバージョンチェックも適用されますが、バージョンは増加しません。