1. ホーム
  2. java

[解決済み] JPA/Hibernateにおけるflush()の正しい使い方

2022-08-22 17:04:33

質問

flush()メソッドについて情報を集めていたのですが、いつ使うのか、どのように使うのが正しいのか、よくわかりません。私が読んだものから、私の理解は、永続性コンテキストの内容がデータベースと同期されること、すなわち未処理のステートメントの発行またはエンティティデータのリフレッシュです。

今、私は2つのエンティティで次のシナリオを得ました。 AB (1対1の関係ですが、JPAでは強制もモデル化もされていません)。 A は複合PKを持ち、これは手動で設定され、また自動生成されたIDENTITYフィールドを持ちます recordId . これは recordId は、エンティティ B を外部キーとして A . 保存している AB を1つのトランザクションで実行します。問題は、自動生成された値である A.recordId を明示的に呼び出さない限り、トランザクション内で利用できないことです。 em.flush() を呼び出した後に em.persist()A . (自動生成されたIDENTITY PKがあれば、その値は直接エンティティで更新されますが、ここではそうではありません)。

できます。 em.flush() は、トランザクション内で使用する際に何か害を及ぼしますか?

どのように解決するのですか?

おそらく、正確には em.flush() の詳細については、実装に依存します。 一般に、HibernateのようなJPAプロバイダは、実際にトランザクションをコミットするまで、データベースに送信するはずのSQL命令をキャッシュすることができます。 たとえば em.persist() を呼び出すと、HibernateはデータベースへのINSERTを行う必要があることを記憶しますが、トランザクションをコミットするまでその命令は実際に実行されません。これは主にパフォーマンス上の理由から行われているようです。

一般的には、自動生成されたキーやデータベーストリガーのような、何らかの副作用の結果が必要なときです。

em.flush() が行うのは、内部の SQL 命令キャッシュを空にし、データベースに対して即座に実行することです。

結論: 害はありませんが、データベースにSQL命令を送信する最適なタイミングに関してJPAプロバイダの決定を上書きしているため、(わずかな)パフォーマンスヒットが発生する可能性があります。