web-dev-qa-db-ja.com

EntityManager.flushは何をし、なぜそれを使用する必要があるのですか?

データベースにオブジェクトを保存するEJBがあります。私が見た例では、このデータが保存されると(EntityManager.persist)、EntityManager.flush()への呼び出しがあります。なぜこれを行う必要があるのですか?保存しているオブジェクトは添付されておらず、後でメソッドで使用されません。実際、一度保存するとメソッドが戻り、リソースが解放されることを期待しています。 (サンプルコードは、remove呼び出しでもこれを行います。)

if (somecondition) {
    entityManager.persist(unAttachedEntity);
} else {
    attachedEntityObject.setId(unAttachedEntity.getId());
}
entityManager.flush();
53
spartikus

EntityManager.flush();への呼び出しは、EntityManager.persist()がそうではないので、データベースにデータを即座に永続化します(EntityManagerの構成方法に応じて: FlushModeType (AUTOまたはCOMMIT)デフォルトではAUTOに設定されており、COMMITに設定されている場合は、トランザクションがコミットされたときに基礎となるデータベースへのデータのパーシスタンスが遅延し、フラッシュが自動的に行われます)。

46

EntityManager.flush()操作を使用して、トランザクションがコミットされる前にすべての変更をデータベースに書き込むことができます。デフォルトでは、JPAは通常、トランザクションがコミットされるまでデータベースに変更を書き込みません。これは、必要になるまでデータベースアクセス、リソース、およびロックを回避するため、通常は望ましい方法です。また、データベースへの書き込みを順序付けし、最適なデータベースアクセスのためにバッチ処理し、整合性制約を維持してデッドロックを回避することもできます。つまり、データベースDMLを永続化、マージ、または削除すると、DML INSERTUPDATEDELETEは、コミットされるまで、またはフラッシュがトリガーされるまで実行されません。

17

EntityManager.persist()はエンティティを永続化しますが、EntityManager.flush()は実際にデータベースでクエリを実行します。

したがって、EntityManager.flush()を呼び出すと、関連するエンティティを挿入/更新/削除するためのクエリがデータベースで実行されます。現時点では、制約の失敗(列幅、データ型、外部キー)がわかります。

具体的な動作は、フラッシュモードがAUTOかCOMMITかによって異なります。

17
Sachin Thapa

したがって、EntityManager.persist()を呼び出すと、エンティティはEntityManagerによって管理されるようになり、Persistence Contextに追加されます(エンティティインスタンス)。明示的なflush()は、エンティティをPersistence Contextに常駐させ、データベースに移動します(SQLを使用)。

Flush()を使用しない場合、このPersistence Contextが関連付けられているトランザクションがコミットされると、これ(Persistence Contextからデータベースへのエンティティの移動)が発生します。

10
Arun