web-dev-qa-db-ja.com

Spring BootおよびSpring Data:Hibernateセッションはどのように管理されますか?

現在、Hibernateと一緒にSpring BootとSpring Data(正確にはJpaRepositoryインターフェイス)を使用するアプリケーションに取り組んでいます。

Hiberanteで気に入っていることの1つは、キャッシュ機能です。特定のオブジェクトに一致する複数のクエリを送信すると、クエリの実行ごとにそのオブジェクトの同じインスタンスが返されます(Javaの==演算子に関して)。ただし、Spring DataクラスとJpaRepositoryクラスを使用する場合、これが常に当てはまるとは限りません。そのため、ここでは複数のHibernateSessionインスタンスが動作していると想定しています。

したがって、私の質問は次のとおりです。SpringDataはHibernateセッションをどのように処理しますか?いつ開閉しますか? Hibernateのオブジェクトキャッシュを最大限に活用するために、アプリケーションのランタイム全体で同じセッションを使用するように設定する方法はありますか? not理由があるのですか?

おかげで、

アラン

38
Alan47

自分で答えを見つけたと思う。誰かがこの質問を見つけた場合、ここに私の答えがあります。

SpringはHibernateセッションをどのように管理しますか?

デフォルトでは、Spring Bootはリポジトリレベルでトランザクション管理を適用します。この場合、JpaRepositoryメソッド(または一般的にRepositoryメソッド)を呼び出すとき、Springは次のことを行います。

  • SessionFactoryに新しいセッションを作成するように依頼します
  • このセッションを開く
  • トランザクションを開く
  • 呼び出されたRepositoryメソッドを実行します
  • トランザクションを閉じます
  • セッションを閉じる

ただし、@Transactionalをサービスクラスまたはメソッドに適用すると、Springはサービスメソッドへのエントリ時にセッションとトランザクションを開き、既存のトランザクション内でリポジトリメソッドが実行されます。

結果は何ですか?

プログラマーとして...

  • トランザクションやセッションにまったく関心を持つ必要はありません。
  • hibernateのキャッシュ機能に依存する場合は、リポジトリよりも大きなスコープで@Transactionalを指定する必要があります。キャッシュは同じHibernateSession内でのみ機能します。
  • javaの@Entity演算子を使用するのではなく、Hibernate ID値によって==オブジェクトの等価性を決定する必要があります。
  • @OneToManyクラス(@EntityではなくFetchMode.LAZYを参照)の遅延コレクション(FetchMode.EAGER参照など)が@Transactional- annotatedメソッド内で排他的に使用されるように注意する必要があります

また、参照用に、次のリンクが非常に役立ちました。 単一セッションの複数のトランザクション

Springの他の多くの側面と同様に、アプリケーションの直接制御を犠牲にする意思がある場合、ここで得られることがたくさんあります。

51
Alan47