6

FlushMode.AUTOが設定されている場合、session.close()を呼び出すと、Hibernateは更新された永続オブジェクトをフラッシュしますか?

session.close()は通常セッションをフラッシュしないことは知っていますが、FlushMode.AUTOがこれにどのように影響するかはわかりません。

ドキュメントから:

FlushMode.AUTO
クエリが古い状態を返さないようにするために、クエリの実行前にセッションがフラッシュされることがあります。これはデフォルトのフラッシュモードです。

これは、セッションが閉じられる前に、変更がフラッシュされることを確認するためにHibernateに依存できることを意味しますか?

小さなコード例:

Session session = HibernateSessionFactory.getSession();  
PersistedObject p = session.get(PersistedObject.class,id);  
p.setSomeProperty(newValue);  
session.close();

更新ドキュメント
によると、これらはセッションがフラッシュされる場所です(AUTOが使用されている場合)

  • いくつかのクエリ実行の前
  • org.hibernate.Transaction.commit()から
  • Session.flush()から

これはSession.close()については何も言いません

4

2 に答える 2

14

Hibernateは(FlushMode.AUTOを使用して)session.close()を呼び出すときに、更新された永続オブジェクトをフラッシュしますか?

いいえ、そうではありません。境界が明確に定義されたトランザクションを使用する必要があります。非トランザクションデータアクセスと自動コミットモードの引用:

Hibernateと非トランザクションで作業する

トランザクション境界なしでデータベースにアクセスする次のコードを見てください。

Session session = sessionFactory.openSession(); 
session.get(Item.class, 123l); 
session.close(); 

デフォルトでは、JDBC構成のJava SE環境では、次のスニペットを実行すると次のようになります。

  1. 新しいセッションが開かれます。この時点では、データベース接続は取得されません。
  2. get()を呼び出すと、SQLSELECTがトリガーされます。これで、セッションは接続プールからJDBC接続を取得します。Hibernateは、デフォルトで、setAutoCommit(false)を使用してこの接続の自動コミットモードをすぐにオフにします。これにより、JDBCトランザクションが効果的に開始されます。
  3. SELECTは、このJDBCトランザクション内で実行されます。セッションが閉じられ、接続がプールに戻され、Hibernateによって解放されます— HibernateはJDBC接続でclose()を呼び出します。コミットされていないトランザクションはどうなりますか?

その質問に対する答えは、「状況によって異なります!」です。JDBC仕様では、接続でclose()が呼び出されたときに、保留中のトランザクションについては何も述べていません。何が起こるかは、ベンダーが仕様をどのように実装するかによって異なります。たとえば、Oracle JDBCドライバーでは、close()を呼び出すとトランザクションがコミットされます。他のほとんどのJDBCベンダーは、JDBC接続オブジェクトが閉じられ、リソースがプールに返されるときに、正常なルートを取り、保留中のトランザクションをロールバックします。

明らかに、これは実行したSELECTにとって問題にはなりませんが、このバリエーションを見てください。

Session session = getSessionFactory().openSession(); 
Long generatedId = session.save(item); 
session.close(); 

このコードは、コミットまたはロールバックされることのないトランザクション内で実行されるINSERTステートメントになります。Oracleでは、このコードはデータを永続的に挿入します。他のデータベースでは、そうではない場合があります。(この状況は少し複雑です。INSERTは、識別子ジェネレータが必要とする場合にのみ実行されます。たとえば、識別子値はINSERTなしのシーケンスから取得できます。その後、永続エンティティはフラッシュ時の挿入までキューに入れられます。このコードで発生します。ID戦略では、値を生成するために即時INSERTが必要です。)

結論:明示的なトランザクション境界を使用します。

于 2010-10-14T09:00:37.640 に答える
0

セッションを閉じると、常にすべての作業がデータベースにフラッシュされます。Flushmode.AUTOは、変更があり、変更されたレコードでテーブルを検索しているときに、データベースに作業をフラッシュします。

于 2010-10-14T08:05:35.793 に答える