データベースにオブジェクトを保存するEJBがあります。私が見た例では、このデータが保存されると(EntityManager.persist)、EntityManager.flush()への呼び出しがあります。なぜこれを行う必要があるのですか?保存しているオブジェクトは添付されておらず、後でメソッドで使用されません。実際、一度保存するとメソッドが戻り、リソースが解放されることを期待しています。 (サンプルコードは、remove呼び出しでもこれを行います。)
if (somecondition) {
entityManager.persist(unAttachedEntity);
} else {
attachedEntityObject.setId(unAttachedEntity.getId());
}
entityManager.flush();
EntityManager.flush();
への呼び出しは、EntityManager.persist()
がそうではないので、データベースにデータを即座に永続化します(EntityManagerの構成方法に応じて: FlushModeType (AUTOまたはCOMMIT)デフォルトではAUTOに設定されており、COMMITに設定されている場合は、トランザクションがコミットされたときに基礎となるデータベースへのデータのパーシスタンスが遅延し、フラッシュが自動的に行われます)。
EntityManager.flush()
操作を使用して、トランザクションがコミットされる前にすべての変更をデータベースに書き込むことができます。デフォルトでは、JPAは通常、トランザクションがコミットされるまでデータベースに変更を書き込みません。これは、必要になるまでデータベースアクセス、リソース、およびロックを回避するため、通常は望ましい方法です。また、データベースへの書き込みを順序付けし、最適なデータベースアクセスのためにバッチ処理し、整合性制約を維持してデッドロックを回避することもできます。つまり、データベースDMLを永続化、マージ、または削除すると、DML INSERT
、UPDATE
、DELETE
は、コミットされるまで、またはフラッシュがトリガーされるまで実行されません。
EntityManager.persist()
はエンティティを永続化しますが、EntityManager.flush()
は実際にデータベースでクエリを実行します。
したがって、EntityManager.flush()
を呼び出すと、関連するエンティティを挿入/更新/削除するためのクエリがデータベースで実行されます。現時点では、制約の失敗(列幅、データ型、外部キー)がわかります。
具体的な動作は、フラッシュモードがAUTOかCOMMITかによって異なります。
したがって、EntityManager.persist()
を呼び出すと、エンティティはEntityManager
によって管理されるようになり、Persistence Context
に追加されます(エンティティインスタンス)。明示的なflush()
は、エンティティをPersistence Context
に常駐させ、データベースに移動します(SQLを使用)。
Flush()を使用しない場合、このPersistence Context
が関連付けられているトランザクションがコミットされると、これ(Persistence Context
からデータベースへのエンティティの移動)が発生します。