ヘッダーをスキップ
Oracle® Fusion Middleware Oracle Coherenceの統合
12c (12.1.2)
B70740-02
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

4 HibernateとCoherenceの統合

この章では、Java環境のオブジェクト関連マッピング・ツールであるHibernateとOracle Coherenceを統合する方法について説明します。Oracle CoherenceとHibernateの機能を組み合せて、たとえば、HibernateをCoherenceのキャッシュ・ストアとして使用したり、CoherenceをHibernateのL2キャッシュとして使用したりすることができます。


注意:

Coherenceコミュニティ・プロジェクトにおけるCoherenceとHibernateの統合に関する追加情報は、次のURLを参照してください。

https://java.net/projects/cohhib


この章では、次の内容を説明します。

4.1 HibernateCacheStoreおよびHibernateCacheLoaderのAPI

Coherenceには、デフォルトのエンティティベースのキャッシュ・ストア実装として、com.tangosol.coherence.hibernateパッケージ内にあるHibernateCacheStore(および対応するキャッシュ・ローダー実装であるHibernateCacheLoader)が組み込まれています。

表4-1は、HibernateCacheStoreクラスとHibernateCacheLoaderクラスの様々なコンストラクタを示しています。詳細な技術情報は、これらのクラスのJavadocを参照してください。

表4-1 Hibernateのキャッシュ・ストア・クラスおよびキャッシュ・ローダー・クラス

クラス名 説明

HibernateCacheLoader()およびHibernateCacheStore()

これらのコンストラクタは、キャッシュ・ローダーまたはキャッシュ・ストアの新しいインスタンスを作成するデフォルト・コンストラクタです。これらは、Hibernate SessionFactoryオブジェクトを作成しません。これらのコンストラクタを使用する場合にHibernate SessionFactoryオブジェクトを作成するには、setSession()メソッドを使用します。

HibernateCacheLoader(java.lang.String entityName)およびHibernateCacheStore(java.lang.String entityName)

これらのコンストラクタは、クラスパスのデフォルトのHibernate構成(hibernate.cfg.xml)を使用して、Hibernate SessionFactoryオブジェクトを作成します。

HibernateCacheStore(java.lang.String entityName, java.lang.String sResource)およびHibernateCacheStore(java.lang.String entityName, java.lang.String sResource)

これらのコンストラクタは、指定された構成ファイル(sResource)に基づいてHibernate SessionFactoryオブジェクトを作成します。

HibernateCacheLoader(java.lang.String entityName, java.io.File configurationFile)およびHibernateCacheStore(java.lang.String entityName, java.io.File configurationFile)

これらのコンストラクタは、指定された構成ファイル(configurationFile)に基づいてHibernate SessionFactoryオブジェクトを作成します。

HibernateCacheStore(java.lang.String entityName, org.hibernate.SessionFactory sFactory)およびHibernateCacheStore(java.lang.String entityName, org.hibernate.SessionFactory sFactory)

これらのコンストラクタは、entityName名およびHibernate SessionFactoryを受け取ります。


4.2 Coherenceのキャッシュ・ストアとしてのHibernateの使用

Hibernateは、Coherenceのキャッシュ・ストア実装としても使用できます。このアプローチを使用するアプリケーションには、一般的に次の特徴があります。

4.2.1 構成要件

HibernateCacheStoreモジュールを使用してアクセスされるHibernateエンティティでは、割り当てられたIDジェネレータを使用する必要があり、定義済のIDプロパティも必要です。

HibernateCacheStoreモジュールで使用されるhibernate.cfg.xmlファイルのhibernate.hbm2ddl.autoプロパティは、過剰なスキーマ更新(および検索)を回避するために無効にしてください。

4.2.2 Hibernateキャッシュ・ストア・コンストラクタの構成

次の例は、エンティティ名のみを受け入れる単純なHibernateCacheStoreコンストラクタの構成方法を示しています。これは、デフォルトの構成パスを使用してHibernateを構成し、クラスパス内でhibernate.cfg.xmlファイルを探します。また、hibernate.cfg.xmlファイルのリソース名またはファイル仕様を第2の<init-paramとして指定することもできます(リソース名の場合は<param-type要素をjava.lang.Stringに設定し、ファイル仕様の場合はjava.io.Fileに設定します)。詳細は、HibernateCacheStoreのJavadocを参照してください。

例4-1は、TableAという名前のNamedCacheキャッシュ・オブジェクトの定義に使用される簡単なcoherence-cache-config.xmlファイルの例を示しています。これによって、Hibernateエンティティ(com.company.TableA)のインスタンスがキャッシュされます。追加のエンティティ・キャッシュを定義するには、<cache-mapping>要素をさらに追加します。

例4-1 Hibernate用のCoherenceキャッシュ構成ファイル

<?xml version="1.0"?>
<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
              xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config coherence-cache-config.xsd">
  <caching-scheme-mapping>
    <cache-mapping>
      <cache-name>TableA</cache-name>
      <scheme-name>distributed-hibernate</scheme-name>
      <init-params>
        <init-param>
          <param-name>entityname</param-name>
          <param-value>com.company.TableA</param-value>
        </init-param>
      </init-params>
    </cache-mapping>
  </caching-scheme-mapping>

  <caching-schemes>
    <distributed-scheme>
      <scheme-name>distributed-hibernate</scheme-name>
      <backing-map-scheme>
        <read-write-backing-map-scheme>
          <internal-cache-scheme>
            <local-scheme></local-scheme>
          </internal-cache-scheme>

          <cachestore-scheme>
            <class-scheme>
              <class-name>
              com.tangosol.coherence.hibernate.HibernateCacheStore
              </class-name>
              <init-params>
                <init-param>
                  <param-type>java.lang.String</param-type>
                  <param-value>{entityname}</param-value>
                </init-param>
              </init-params>
            </class-scheme>
          </cachestore-scheme>
        </read-write-backing-map-scheme>
      </backing-map-scheme>
    </distributed-scheme>
  </caching-schemes>
</cache-config>

例4-2では、事前定義マクロ{cache-name}を使用して、キャッシュ・マッピングの<init-params>部分を不要にできることも示しています。

例4-2 {cache-name}マクロを使用したCoherenceキャッシュ構成ファイル

<?xml version="1.0"?>

<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
              xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config coherence-cache-config.xsd">
  <caching-scheme-mapping>
    <cache-mapping>
      <cache-name>TableA</cache-name>
      <scheme-name>distributed-hibernate</scheme-name>
    </cache-mapping>
  </caching-scheme-mapping>

  <caching-schemes>
    <distributed-scheme>
      <scheme-name>distributed-hibernate</scheme-name>
      <backing-map-scheme>
        <read-write-backing-map-scheme>
          <internal-cache-scheme>
            <local-scheme></local-scheme>
          </internal-cache-scheme>

          <cachestore-scheme>
            <class-scheme>
              <class-name>
              com.tangosol.coherence.hibernate.HibernateCacheStore
              </class-name>
              <init-params>
                <init-param>
                  <param-type>java.lang.String</param-type>
                  <param-value>com.company.{cache-name}</param-value>
                </init-param>
              </init-params>
            </class-scheme>
          </cachestore-scheme>
        </read-write-backing-map-scheme>
      </backing-map-scheme>
    </distributed-scheme>
  </caching-schemes>
</cache-config>

例4-3では、命名規則で許可される場合は、マッピングを完全に汎用化して、任意の修飾されたクラス名(エンティティ名)のキャッシュ・マッピングを使用できることを示しています。

例4-3 汎用マッピングを指定したcoherence-cache-config.xmlファイルのサンプル

<?xml version="1.0"?>

<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
              xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config coherence-cache-config.xsd">
  <caching-scheme-mapping>
    <cache-mapping>
      <cache-name>com.company.*</cache-name>
      <scheme-name>distributed-hibernate</scheme-name>
    </cache-mapping>
  </caching-scheme-mapping>

  <caching-schemes>
    <distributed-scheme>
      <scheme-name>distributed-hibernate</scheme-name>
      <backing-map-scheme>
        <read-write-backing-map-scheme>
          <internal-cache-scheme>
            <local-scheme></local-scheme>
          </internal-cache-scheme>

          <cachestore-scheme>
            <class-scheme>
              <class-name>
              com.tangosol.coherence.hibernate.HibernateCacheStore
              </class-name>
              <init-params>
                <init-param>
                  <param-type>java.lang.String</param-type>
                  <param-value>{cache-name}</param-value>
                </init-param>
              </init-params>
            </class-scheme>
          </cachestore-scheme>
        </read-write-backing-map-scheme>
      </backing-map-scheme>
    </distributed-scheme>
  </caching-schemes>
</cache-config>

4.2.3 Hibernateキャッシュ・ストアの作成

提供されるHibernateCacheStoreモジュールには、ほとんどのエンティティベース・キャッシュに対するソリューションが用意されていますが、アプリケーション固有のCacheStoreモジュールが必要な場合もありますたとえば、パラメータ化された問合せの使用や、問合せ結果の組込みまたは後処理などの場合です。

4.2.3.1 リエントラント・コール

キャッシュ・ストアでバッキングされたキャッシュ実装では、アプリケーション・スレッドがキャッシュ・データにアクセスすると、キャッシュ操作が管理CacheService APIを使用して、関連するCacheStore実装に対するコールをトリガーする場合があります。CacheStoreは、CacheService APIに対するコール・バックを実行できません。これは間接的には、Hibernateがキャッシュ・データへのアクセスを試行できないことを意味します。そのため、CacheLoader実装またはCacheStore実装のすべてのメソッドで、Session.setCacheMode(CacheMode.IGNORE)メソッドをコールするようにして、キャッシュ・アクセスを無効にしておく必要があります。または、Hibernate構成で、キャッシュが無効化されたCacheStore実装のバージョンを使用してクローニングする必要があります(プログラムで実行するか、hibernate.cfg.xmlファイルを使用します)。

4.2.4 Hibernateキャッシュ・ストア機能の拡張

場合によっては、アプリケーション固有の機能でHibernateキャッシュ・ストアを拡張できます。最も明白な事例として、既存のプログラムで構成されたSessionFactoryインスタンスを利用する場合があります。

4.2.5 JDBC分離レベル

データベースへのすべてのアクセスがCoherenceを介して実行される場合、読取り操作と書込み操作が(パーティション・キャッシュ・サービスを使用して)キーごとにシリアルで実行されるため、キャッシュ・ストア・モジュールによって必然的にANSIスタイルの反復可能読取りの分離が強制されます。キャッシュ・ストアの操作は複数のパーティション・キャッシュ・ノード(つまり、複数のデータベース・トランザクション)にまたがる場合があるため、反復可能読取りレベルを超えるデータベース分離を設定しても、さらに分離されるわけではありません。反復可能読取りレベルよりも低いデータベース分離レベルを使用すると、予期しない異常が発生せず、データベース・サーバー上の処理負荷が減少する場合があります。

4.2.6 Hibernateキャッシュ・ストア操作のフォルト・トレランス

single-cache-entry更新の場合、サーバー障害時(部分更新時の障害を含む)のキャッシュとデータベースの整合性が保証されるため、キャッシュ・ストア操作は完全にフォルト・トレラントになります。フォルト・トレランスには様々なメカニズムがありますが、これはライトスルーとライトビハインドの両方のキャッシュで当てはまります。

Coherenceは、複数のキャッシュ・ストア・インスタンスにまたがる、2フェーズのキャッシュ・ストア操作をサポートしていません。つまり、2つのキャッシュ・エントリが更新されて、別のサーバー上にあるキャッシュ・ストア・モジュールへのコールがトリガーされる場合、一方のデータベースでは更新が成功しますが、もう一方では失敗する可能性があります。この場合、アプリケーション・サーバーのトランザクション・マネージャで、キャッシュアサイド・アーキテクチャ(キャッシュとデータベースを、単一トランザクション内の2つの別個のコンポーネントとして更新する)を使用できます。ほとんどの場合、論理コミットの失敗を回避するように(当然、サーバー障害も発生しないように)データベース・スキーマを設計することが可能です。ライトビハインド・キャッシングでは、put操作がデータベース動作の影響を受けないため(そして、根本的な問題は設計プロセスの初期段階で解決されているため)、この問題は回避されます。

4.2.7 完全にキャッシュされたデータセットの使用

完全にキャッシュされたデータセットの使用が有用なシナリオは、2つあります。1つは、キャッシュで分散問合せを実行する場合で、もう1つは、データベースの障害時でもアプリケーションの処理を続行させる場合です。

4.2.7.1 分散問合せ

分散問合せでは、データベース・サーバーでの問合せの実行と比べて、待機時間の短縮、スループットの向上、データベース・サーバー負荷の低減が実現される可能性があります。セット指向の問合せの場合、正しい問合せ結果を生成するには、データセット全体をキャッシュする必要があります。具体的に言うと、キャッシュに対して発行された問合せで正しい結果を得るには、その問合せはキャッシュされていないデータに依存できません。

分散問合せによりハイブリッド・キャッシュを作成できます。たとえば、問合せ用の完全にキャッシュされたサイズ制限のあるデータセット(先週のデータなど)や、シングルトンの読取りに使用される部分的にキャッシュされた履歴データセットなど、2つの用途のNamedCacheを組み合せることができます。これは、データの複製を回避し、メモリー使用量を抑えるためのアプローチです。

完全にキャッシュされたデータセットは通常、アプリケーションの起動時に(または定期的に)バルクロードされますが、キャッシュ・ストア統合を使用して、キャッシュとデータベースを両方を完全に同期することもできます。

4.2.7.2 接続解除処理

完全にキャッシュされたデータセットを使用するもう1つの理由として、基礎となるデータベースが停止した後でもアプリケーション処理を続行する機能を提供することがあります。ライトビハインド・キャッシュを使用すると、この操作モードが拡張されて完全な読取り/書込みアプリケーションがサポートされます。ライトビハインドの場合、キャッシュは(実質的に)一時的な記録システムになります。データベースに障害が発生した場合、接続が回復するまで、更新内容がCoherenceのキューに置かれます。回復した時点で、すべてのキャッシュ変更がデータベースに送信されます。

4.3 HibernateのL2キャッシュ・プロバイダとしてのCoherenceの使用

CoherenceをHibernate L2キャッシュ・プロバイダとして使用すると、同じHibernateアプリケーションを実行する複数のJVMでL2キャッシュを共有できます。この場合のCoherenceキャッシングの使用は、Hibernateによって制御されます。このプロバイダを適切に使用するには、Hibernate L2キャッシングについてよく理解しておく必要があります。L2キャッシュとしてのHibernateの詳細は、次のHibernateリファレンス・マニュアルの「パフォーマンスの向上」を参照してください。

http://www.hibernate.org/docs.html

これは、次の特徴を持つアプリケーションに適合する可能性があります。

Hibernateは、次の3つの主要なキャッシング形式をサポートしています。

sessionキャッシュは、Hibernate Session内のレコードのキャッシングを行います。Hibernate Sessionは、永続データのトランザクションレベルのキャッシュであり、複数のデータベース・トランザクションにまたがる可能性があり、通常はスレッドごとに範囲設定されます。セッション・キャッシュは、非クラスタ・キャッシュ(定義による)として、Hibernateによって全面的に管理されます。

L2および問合せキャッシュは、複数のトランザクションにまたがり、キャッシュ・プロバイダとしてCoherenceの使用がサポートされます。L2キャッシュは、複数のセッションにわたるレコードのキャッシュを(主キーの検索用に)行います。問合せキャッシュは、Hibernate問合せによって生成された結果セットをキャッシュします。Hibernateでは、L2および問合せキャッシュにおいてデータを内部形式で管理するため、これらのキャッシュはHibernateでのみ使用可能です。詳細は、『Hibernate Reference Documentation』(Hibernateに付属)の、2次レベル・キャッシュに関する項を参照してください。

4.3.1 Hibernate L2キャッシュとしてのCoherenceの構成

HibernateでCoherenceキャッシュ・プロバイダを使用するには、hibernate.cache.provider_classプロパティでCoherenceプロバイダ・クラスを指定します。通常、これはデフォルトのHibernate構成ファイルhibernate.cfg.xmlで構成します。例4-4は、CoherenceCacheProvider (com.tangosol.coherence.hibernate.CacheProvider)をhibernate.cache.provider_classプロパティの値としてコールするproperty要素を示しています。

例4-4 Coherenceプロバイダ・クラスの指定

<property name="hibernate.cache.provider_class">com.tangosol.coherence.hibernate.CoherenceCacheProvider</property>

coherence-hibernate.jarファイル(lib/サブディレクトリにある)をアプリケーション・クラスパスに追加する必要があります。

Hibernateは、構成プロパティhibernate.cache.use_minimal_putsで、キャッシュの読取りを増加およびキャッシュの更新を最小化することによって、クラスタ・キャッシュのキャッシュ・アクセスが最適化されます。これは、Coherenceキャッシュ・プロバイダによってデフォルトで有効になっています。このプロパティをfalseに設定すると、キャッシュ管理のオーバーヘッドの増加およびトランザクション・ロールバック数の増加を招く場合があります。

Coherenceキャッシュ・プロバイダでは、タイムアウトになるまでのロック獲得の試行時間を設定できます。この値を指定するには、Javaプロパティtangosol.coherence.hibernate.lockattemptmillisを使用します。デフォルトは1分です。

4.3.2 Coherenceキャッシュ・トポロジの指定

デフォルトでは、Coherenceキャッシュ・プロバイダは、coherence-hibernate.jarファイルにあるconfig/hibernate-cache-config.xmlという名前のカスタム・キャッシュ構成を使用します。この構成ファイルで、Hibernate L2キャッシュのキャッシュ・マッピングを定義します。必要に応じて、tangosol.coherence.hibernate.cacheconfig Javaプロパティを使用して、Hibernate L2キャッシュに対して代替のキャッシュ構成リソースを指定できます。マッピングが適切に構成されている場合、このプロパティをアプリケーションのメインcoherence-cache-config.xmlファイルをポイントするように構成できます。Hibernate固有のキャッシュの管理に専用のキャッシュ・サービスを使用して、キャッシュ・ストア・モジュールでCoherence管理のHibernate L2キャッシュに対するリエントラント・コール・バックが行われないようにすると有益な場合があります。

Coherenceキャッシュ構成ファイルのスキーム・マッピング・セクションでは、hibernate.cache.region_prefixプロパティでキャッシュ・トポロジを指定できます。たとえば、キャッシュ構成ファイルにnear-*のワイルドカード・マッピングがあり、Hibernateリージョンの接頭辞プロパティがnear-に設定されている場合、すべてのHibernateキャッシュがnear-接頭辞を使用して名前付けされ、near-*キャッシュ名パターンで指定したキャッシュ・スキーム・マッピングが使用されます。

接頭辞と修飾エンティティ名の組合せ(たとえば、near-com.company.EntityName)からキャッシュ・マッピングを作成することによって、または、空白の接頭辞を設定し、修飾エンティティ名のそれぞれにキャッシュ・マッピングを指定することによって、エンティティ別にキャッシュ・トポロジを指定できます。

L2キャッシュは、メモリー使用量が過剰にならないようにサイズを制限する必要があります。Hibernate APIには、完全なエビクション以外に問合せキャッシュを制御する手段がないため、問合せキャッシュでは特にサイズ制限が必要です。

4.3.3 キャッシュの同時実行性戦略の選択

Hibernateでは、通常、キャッシュとデータベースの両方でオプティミスティックな同時実行性の使用が重視されます。特に、オプティミスティックな同時実行性では、トランザクションの開始時にアプリケーションで正確なデータを利用できるかどうかが、トランザクション処理では特に重要になります。データが不正確な場合、コミット処理の際にトランザクションが不正確なデータに基づいていることが検出され、トランザクションはコミットされません。オプティミスティックなトランザクションのほとんどは、基礎となるデータへの他のプロセスによる変更に対して調整する必要がありますが、キャッシングを使用すると、キャッシュ自体が古くなる可能性が高くなります。Hibernateには、L2キャッシュに対する更新を制御する複数のキャッシュ同時実行性戦略が用意されています。Coherenceでは、クラスタ全体でのキャッシュの一貫性がサポートされるため、さほどの問題は生じませんが、キャッシュの同時実行性戦略を適切に選択することで、アプリケーションの効率の向上につながります。

キャッシュ構成戦略は、表レベルで指定できます。一般に、この戦略はクラスのマッピング・ファイルで指定する必要があります。

読取りと書込みが行われるアクティビティでは、read-write戦略をお薦めします。トランザクション戦略は、nonstrict-read-write戦略と同様に実装され、Hibernateのオプティミスティックな同時実行性機能に依存しています。アプリケーションによるデータの更新頻度が少なく、厳密なトランザクション分離を必要としない場合は、nonstrict-read-write戦略が適しています。オプティミスティックな同時実行性に対する影響が許容できる場合は、nonstrict-read-writeのほうがパフォーマンスが高くなることがあります。

読取り専用キャッシングでは、基礎となるデータベースのデータに変更が発生しても、若干古いデータを許容できる場合に、nonstrict-read-write戦略を使用します。基礎となるデータベースのデータに変更が発生しない場合は、read-only戦略を使用します。

4.3.4 問合せキャッシュ

問合せ結果をキャッシュするには、hibernate.cache.use_query_cacheプロパティをtrueに設定します。これで、結果をキャッシュする必要のある問合せを発行するたびに、Query.setCacheable(true)メソッドが使用されます。Hibernateのorg.hibernate.cache.QueryKeyインスタンスは、バイナリで比較できないため(順序付けされていないデータ・メンバーの非deterministicシリアライズが実行されているため)、問合せ結果の格納にはサイズ制限のあるローカル・キャッシュまたはレプリケート・キャッシュを使用します(これにより、キーの比較にhashcode()またはequals()メソッドが強制的に使用されます)。

デフォルトの問合せキャッシュ名は、org.hibernate.cache.StandardQueryCacheです(デフォルトのリージョン接頭辞が指定されていない場合。この場合、キャッシュ名の前に[prefix].が付加されます)。キャッシュ構成ファイルを使用して、このキャッシュ名をローカルまたはレプリケーション・トポロジにマップするか、問合せ時に適切にマップされたリージョン名を明示的に指定します。

4.3.5 Hibernate L2キャッシュのフォルト・トレランス

Hibernate L2キャッシュ・プロトコルでは、クライアントまたはサーバーの障害発生時の完全なフォルト・トレランスがサポートされます。read-writeのキャッシュ同時実行性戦略では、Hibernateによって更新トランザクションの開始時にキャッシュからアイテムがロックアウトされるため、クライアント側の障害では、キャッシュされないエンティティとコミットされていないトランザクションが発生するだけです。サーバー側の障害は、Coherenceによって透過的に処理されます(指定したデータ・バックアップ・カウントによって異なります)。

4.3.6 デプロイメント

統合されたクラス・ローダーがないアプリケーション・サーバーで使用する場合、Coherenceキャッシュ・プロバイダをアプリケーションの一部としてデプロイして、アプリケーション専用のクラス・ローダーを使用できるようにしておく必要があります(オブジェクトのシリアライズとデシリアライズに必要です)。