回答:
セッションをフラッシュすると、Hibernateはのメモリ内状態をSession
データベースと同期します(つまり、変更をデータベースに書き込みます)。デフォルトでは、Hibernateは変更を自動的にフラッシュします。
を明示的にフラッシュSession
できるようにすると、状況によっては必要になる可能性のある細かい制御が可能になります(IDの割り当て、セッションのサイズの制御など)。
上記の回答で正しく述べたように、呼び出すflush()
ことにより、HibernateはデータベースでSQLコマンドを実行します。ただし、変更はまだ「コミット」されていないことを理解してください。したがって、フラッシュを実行した後、コミットを実行する前に、DBに直接(たとえば、SQLプロンプトから)アクセスし、変更された行を確認すると、変更は表示されません。
これは、2つのSQLコマンドセッションを開くのと同じです。また、1つのセッションで行われた変更は、コミットされるまで他のユーザーには表示されません。
session.flush()
ステートメントを呼び出すとデータベースで実行されますが、コミットされないことがわかります。
我々は呼んでいないと仮定しflush()
たセッションオブジェクトのメソッドを、我々は法を犯す呼び出す場合、それは内部的にデータベース上の文を実行してからコミットの作業を行います。
commit=flush+commit
(機能の場合)
したがって、Sessionオブジェクトでメソッドflush()を呼び出すと、コミットは行われませんが、データベースにヒットしてクエリを実行し、ロールバックも取得すると結論付けます。
コミットするには、Transactionオブジェクトでcommit()を使用します。
セッションをフラッシュすると、現在セッション内にあるデータがデータベース内のデータと同期されます。
Hibernate Webサイトの詳細:
flush()
セッションがいつJDBC呼び出しを実行するかについての保証はまったくなく、使用する場合を除いて、それらが実行される順序のみが保証されるため、便利ですflush()
。
を使用flush
して、トランザクションがコミットされたときではなく、既知の場所で検証制約を実現および検出することができます。commit
一部のフレームワークロジック、宣言型ロジック、コンテナ、またはテンプレートによって暗黙的に呼び出される可能性があります。この場合、スローされた例外はキャッチして処理することが難しい場合があります(コードで高すぎる可能性があります)。
たとえばsave()
、アドレスに一意の制約がある新しいEmailAddressオブジェクトの場合、コミットするまでエラーは発生しません。
呼び出すとflush()
強制的に行が挿入され、重複がある場合は例外がスローされます。
ただし、例外の後でセッションをロールバックする必要があります。
上記のすべての回答をまとめて、Flush()メソッドをSession.save()と関連付けて、より重要なものにしたいと思います。
Hibernate save()を使用して、エンティティをデータベースに保存できます。このメソッドはトランザクションの外部で呼び出すことができるため、データを保存するためにこのメソッドを使用したくありません。トランザクションなしでこれを使用し、エンティティ間のカスケードがある場合、セッションをフラッシュしない限り、プライマリエンティティのみが保存されます。
flush():セッションを強制的にフラッシュします。セッションデータをデータベースと同期するために使用されます。
session.flush()を呼び出すと、ステートメントはデータベースで実行されますが、コミットされません。session.flush()を呼び出さず、session.commit()を呼び出す場合、内部的にcommit()メソッドがステートメントを実行してコミットします。
つまり、commit()= flush + commitです。そのため、session.flush()はデータベース内のステートメントを実行するだけで(コミットはしません)、ステートメントはもうメモリ内にありません。セッションを強制的にフラッシュするだけです。
いくつかの重要なポイント:
トランザクション境界の外に保存することは避けてください。そうしないと、マップされたエンティティが保存されず、データの不整合が発生します。例外や警告をスローしないため、セッションのフラッシュを忘れることはごく普通のことです。デフォルトでは、Hibernateは変更を自動的にフラッシュします。トランザクションがコミットされたときにクエリを実行する前に、明示的にセッションをフラッシュできるようにすると、状況によっては(IDを割り当てたり、セッションのサイズを制御したりするために)より細かい制御が必要になる場合があります)
このflush()
メソッドにより、Hibernateはセッションをフラッシュします。setFlushMode()
メソッドを使用して、セッションでフラッシュモードを使用するようにHibernateを構成できます。現在のセッションのフラッシュモードを取得するには、getFlushMode()
メソッドを使用できます。セッションがダーティかどうかを確認するには、isDirty()
メソッドを使用します。デフォルトでは、Hibernateはセッションのフラッシュを管理します。
ドキュメントに記載されているように:
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html
フラッシング
フラッシュは、永続化コンテキストの状態を基礎となるデータベースと同期させるプロセスです。
EntityManager
そしてHibernateはSession
、アプリケーション開発者は、エンティティの永続状態を変更することができ、それを通してメソッドのセットを公開します。永続化コンテキストは、トランザクションのライトビハインドキャッシュとして機能し、エンティティの状態変化をキューに入れます。後書きキャッシュと同様に、変更は最初にメモリー内に適用され、フラッシュ時にデータベースと同期されます。フラッシュ操作は、すべてのエンティティの状態変化を受け取り
INSERT
、それを、UPDATE
またはDELETE
ステートメントに変換します。フラッシュ戦略は、現在実行中のHibernateセッションのflushModeによって指定されます。JPAが定義しているフラッシュ戦略は2つ(
AUTO
とCOMMIT
)だけですが、Hibernateのフラッシュタイプのスペクトルははるかに広くなっています。
ALWAYS
:すべてのクエリの前にセッションをフラッシュします。AUTO
:これはデフォルトのモードであり、必要な場合にのみセッションをフラッシュします。COMMIT
:セッションは、現在のトランザクションがコミットされるまでフラッシュを遅らせようとしますが、時期尚早にフラッシュする可能性もあります。MANUAL
:セッションのフラッシュはアプリケーションに委任されます。アプリケーションSession.flush()
は永続化コンテキストの変更を適用するために明示的に呼び出す必要があります。デフォルトでは、Hibernateは
AUTO
次の状況でフラッシュをトリガーするフラッシュモードを使用します。
- トランザクションをコミットする前。
- キューに入れられたエンティティアクションと重複するJPQL / HQLクエリを実行する前。
- 同期が登録されていないネイティブSQLクエリを実行する前。