第3章 設定

Hibernateはさまざまな環境で動作するようにデザインされているため、非常に多くの設定要素があります。 幸いなことに、Hibernateは、公開されているパッケージの etc/ フォルダの hibernate.properties に、ほとんどの設定要素の適切なデフォルト値が記述されています。 この hibernate.properties をクラスパスに設定し、設定要素をカスタマイズするだけです。

3.1. プログラム上の設定

org.hibernate.cfg.Configuration のインスタンスは、 Javaの型とSQLデータベースのマッピング情報をすべて持っています。 The Configuration は、(不変の) SessionFactory を生成するときに使用します。 複数のXMLマッピングファイルを変換し、マッピング情報にします。

通常、Configuration インスタンスは、特定のXMLマッピングファイル によって直接初期化されます。もし、マッピングファイルがクラスパスに設定されている場合、 次のメソッドを使ってください。 addResource() :

Configuration cfg = new Configuration()
    .addResource("Item.hbm.xml")
    .addResource("Bid.hbm.xml");

代替案(こちらのほうが良いときもあります)としてマッピングクラスを指定する方法もあります。Hibernateに、マッピングファイルを 見つけさせてください:

Configuration cfg = new Configuration()
    .addClass(org.hibernate.auction.Item.class)
    .addClass(org.hibernate.auction.Bid.class);

Hibernateは、クラスパスにある以下のような名前のマッピングファイルを見つけます。 /org/hibernate/auction/Item.hbm.xml/org/hibernate/auction/Bid.hbm.xml 。 この方法だと、ハードコーディングされたファイル名を排除できます。

Configuration は、設定プロパティを指定することもできます:

Configuration cfg = new Configuration()
    .addClass(org.hibernate.auction.Item.class)
    .addClass(org.hibernate.auction.Bid.class)
    .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
    .setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
    .setProperty("hibernate.order_updates", "true");

Hibernateに設定プロパティを通す方法は1つではありません。 さまざまなオプションを用意しています:

  1. java.util.Properties インスタンスを Configuration.setProperties() に渡します。

  2. hibernate.properties を クラスパスのルートディレクトリに置きます。

  3. System プロパティが java -Dproperty=value を使うように設定します。

  4. <property> 要素を hibernate.cfg.xml (後述)に設定します。

今すぐ始めたいのなら、hibernate.properties を使うのが一番の近道です。

Configuration は、起動時にだけあるオブジェクトであり、 一度 SessionFactory を生成した後は、破棄されることを意図しています。

3.2. SessionFactoryを取得する

Configuration がすべてのマッピング情報を解析したら、 アプリケーションは、 Session ファクトリインスタンスを取得します。 このSessionFactoryは、Hibernateを使用するすべてのスレッドで共有されるべきです。

SessionFactory sessions = cfg.buildSessionFactory();

Hibernateは、 SessionFactory を複数生成することができます。 これは、複数のデータベースを使用する場合に便利です。

3.3. JDBCコネクション

通常、開発者は SessionFactory を生成し、SessionFactoryでJDBCコネクションをプーリングしたいと考えます。 そのアプローチを採用する場合、単純に Session をオープンしてください:

Session session = sessions.openSession(); // open a new Session

これだけで、プーリングしたJDBCコネクションを使って目的のデータベース にアクセスすることができます。

そのためには、JDBCコネクションのプロパティをHibernateに設定する必要があります。 すべてのHibernateプロパティ名とセマンティクスは org.hibernate.cfg.Environment クラスに定義されています。 この設定はJDBCコネクション設定の中で一番重要なものです。

もし、以下のプロパティを設定すると、Hibernateはコネクションを取得する(プールも)ために java.sql.DriverManager を使います。

表 3.1. Hibernate JDBCプロパティ

プロパティ名意味
hibernate.connection.driver_classJDBCドライバクラス
hibernate.connection.urljdbc URL
hibernate.connection.usernamedatabase user
hibernate.connection.passworddatabase user password
hibernate.connection.pool_sizeプールするコネクションの最大数

Hibernateのコネクションプールアルゴリズムは非常に初歩的なものです。 これはすぐに始められるようにと用意されたもので、製品として使用することを意図していません 。 また、パフォーマンスのテストのためのものでもありません。 最高のパフォーマンスと安定性を持ったプールを実現したければ、サードパーティのツールをお勧めします。 hibernate.connection.pool_size プロパティに 適切なコネクションプールサイズを記述してください。 このままだとHibernateのコネクションプールを使います。 例えば次のようにC3P0を使います。

C3P0はオープンソースJDBCコネクションプールで、Hibernateの lib ディレクトリにあります。もし、hibernate.c3p0.* プロパティを セットすれば、Hibernateは、 C3P0ConnectionProvider を使います。 もしProxoolを使いたい場合は、 hibernate.properties パッケージを 参照したり、HibernateのWebサイトでより多くの情報を取得してください。

C3P0用の hibernate.properties ファイルを例として示します:

hibernate.connection.driver_class = org.postgresql.Driver
hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
hibernate.connection.username = myuser
hibernate.connection.password = secret
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

アプリケーションサーバ上で使う場合は、Hibernateを設定し、 アプリケーションサーバからコネクションを取得するようにしてください。 Datasource をJNDIに登録します。そして プロパティを以下のように設定してください。

表 3.2. Hibernate データソースプロパティ

プロパティ名意味
hibernate.connection.datasourceデータソースのJNDI名
hibernate.jndi.urlJNDIプロバイダのURL (オプション)
hibernate.jndi.classJNDIクラス InitialContextFactory (オプション)
hibernate.connection.usernamedatabase user (オプション)
hibernate.connection.passworddatabase user password (オプション)

アプリケーションサーバから提供されたJNDIデータソースを使う hibernate.properties ファイルの例を示します:

hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = \
    org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = \
    org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

JNDIデータソースから取得したJDBCコネクションは、アプリケーションサーバの コンテナ管理トランザクションに自動的に参加します。

任意のコネクションプロパティは、与えられた” hibernate.connnection ” プロパティ名によって与えられます。例えば、 charSet を設定したい場合は、 hibernate.connection.charSet を使います。

JDBCコネクションを取得する戦略を持つ独自のプラグインを定義する場合は、 org.hibernate.connection.ConnectionProvider インターフェイスを 実装してください。そして、実装クラスを hibernate.connection.provider_class に設定してください。

3.4. オプション設定プロパティ

これらのプロパティはHibernateの挙動を制御するものです。 これらのプロパティはすべて妥当なデフォルト値があり、任意で設定します。

注意:これらのプロパティは"システムレベル"のみです。 システムレベルプロパティは java -Dproperty=value 、もしくは hibernate.properties でのみ設定可能です。 それ以外の設定方法は ありません

表 3.3. Hibernate設定プロパティ

プロパティ名意味
hibernate.dialect Hibernate Dialect クラス名が入ります。 これはリレーショナルデータベースごとに最適化されたSQLを生成します。

例: full.classname.of.Dialect

hibernate.show_sql 発行されたすべてのSQLをコンソールに出力します。 これはログカテゴリの org.hibernate.SQLdebug を設定する方法の代替手段です。

例: true | false

hibernate.format_sql ログとコンソールのSQLを美しく表示します。

例: true | false

hibernate.default_schema 生成されるSQL文のテーブルに設定するスキーマ/テーブルスペースです。

例: SCHEMA_NAME

hibernate.default_catalog 生成されるSQL文のテーブルに設定するカタログです。

例: CATALOG_NAME

hibernate.session_factory_nameSessionFactory は生成後、この名前でJNDIに登録されます。

例: jndi/composite/name

hibernate.max_fetch_depth 外部結合フェッチの最大深度を設定します。結合する関連は 対一関連のみ(一対一、多対一)です。 0 を指定すると外部結合フェッチは無効になります。

例: 推奨する値は 0 から 3 です。

hibernate.default_batch_fetch_size 関連フェッチのデフォルトバッチサイズを指定します。

例: 推奨する値は 4 , 8 , 16 です。

hibernate.default_entity_modeSessionFactory からセッションをオープンしたときに 使用するエンティティのデフォルトモードを設定します。

dynamic-map, dom4j, pojo

hibernate.order_updates 項目が更新されたときに、別のSQLで主キーを更新することを強制します。 この場合、同時実行可能なシステムでは、まれにデッドロックが発生する可能性があります。

例: true | false

hibernate.generate_statistics 有効の場合、Hibernateはパフォーマンスチューニングに 有効な統計情報を収集します。

例: true | false

hibernate.use_identifer_rollback 有効の場合、オブジェクトが削除されたときに 識別子プロパティをリセットし、デフォルト値にしたものを生成します。

例: true | false

hibernate.use_sql_comments 有効の場合、SQL内にコメントを生成します。これはデバックを容易にします。 デフォルトの値は false です。

例: true | false

表 3.4. Hibernate JDBC とコネクションプロパティ

プロパティ名意味
hibernate.jdbc.fetch_size 値が0でない場合、JDBCフェッチサイズを決定します ( Statement.setFetchSize() を呼びます)。
hibernate.jdbc.batch_size 値が0でない場合、HibernateがJDBC2バッチ更新を使用します。

例: 推奨する値は 5 から 30 です。

hibernate.jdbc.batch_versioned_data もしJDBCドライバが executeBatch() によって正確な行数を 返す場合、このプロパティを true にしてください (通常はこのオプションをONにします)。 Hibernateは、自動バージョンデータのためバッチDMLを使います。 デフォルトの値は false です。

例: true | false

hibernate.jdbc.factory_class カスタム Batcher を選びます。 ほとんどのアプリケーションに、この設定は必要ありません。

例: classname.of.Batcher

hibernate.jdbc.use_scrollable_resultset スクロール可能なリザルトセットを、Hibernateが使用します。 このプロパティは、JDBCコネクションがコネクションメタデータを サポートしていることが必須条件になります。

例: true | false

hibernate.jdbc.use_streams_for_binary JDBCへ/から binaryserializable の書き込み/読み込みストリームを使います(システムレベルのプロパティ)。

例: true | false

hibernate.jdbc.use_get_generated_keys 挿入の後に自動生成された主キーを取得するための JDBC3 PreparedStatement.getGeneratedKeys() の使用を有効にします。 これはJDBC3+ドライバとJRE1.4+を必要とし、 もしHibernateの識別子ジェネレータに問題が発生するようならfalseに設定してください。 デフォルトではコネクションメタデータを使いドライバの能力を決定します。

例: true|false

hibernate.connection.provider_class JDBCコネクションをHibernateに提供する独自の ConnectionProvider の 名前を指定します。

例: classname.of.ConnectionProvider

hibernate.connection.isolation JDBCトランザクション分離レベルを設定します。 妥当な値を調べるためには java.sql.Connection をチェックしてください。 しかし使用するデータベースが、すべての分離レベルをサポートしているとは限りません。

例: 1, 2, 4, 8

hibernate.connection.autocommit プールされているJDBCコネクションの自動コミットを有効にする(非推奨)。

例: true | false

hibernate.connection.release_mode HibernateがJDBCコネクションをリリースするかを指定します。デフォルトでは セッションが明示的にクローズまたは切断されてもコネクションは保持します。 アプリケーションサーバのJTAデータソースの場合、 すべてのJDBCコールの後、強制的にコネクションをリリースするために after_statement を 使ってください。 非JTAコネクションの場合、各トランザクションが終了したときに after_transaction を使い、コネクションをリリースしてください。 auto にすると、 JTAやCMTトランザクションの場合、 after_statement でクローズし、 JDBCトランザクションの場合、 after_transaction でクローズします。

例: auto (default) | on_close | after_transaction | after_statement

Note that this setting only affects Sessions returned from SessionFactory.openSession. For Sessions obtained through SessionFactory.getCurrentSession, the CurrentSessionContext implementation configured for use controls the connection release mode for those Sessions. See 項2.5. 「コンテキスト上のセッション」 注意してください。この設定は SessionFactory.openSession から 取得した Session だけに効果があります。 SessionFactory.getCurrentSession を通じて取得した Session では、CurrentSessionContext の実装によって、コネクションのリリースモードを設定します。 項2.5. 「コンテキスト上のセッション」 を参照してください。

hibernate.connection.<propertyName> JDBCの propertyName プロパティを、 DriverManager.getConnection() に渡します。
hibernate.jndi.<propertyName>propertyName プロパティを、 JNDI InitialContextFactory に渡します。

表 3.5. Hibernate キャッシュプロパティ

プロパティ名意味
hibernate.cache.provider_class カスタム CacheProvider のクラス名です。

例: classname.of.CacheProvider

hibernate.cache.use_minimal_puts 書き込みを最小限にするために、二次キャッシュの操作を最適化します。 その代わりに、読み込みがより頻繁に発生するようになります。 このセッティングはクラスタキャッシュで役に立ちます。 Hibernate3ではクラスタキャッシュ実装用にデフォルトでは有効になっています。

例: true|false

hibernate.cache.use_query_cache 特定のクエリがキャッシュ可能な場合に、クエリキャッシュを有効にします。

例: true|false

hibernate.cache.use_second_level_cache 二次キャッシュを完全に無効にする場合に使います。 デフォルトでは有効で、クラスの <cache> マッピング で制御します。

例: true|false

hibernate.cache.query_cache_factory カスタム QueryCache インターフェイスのクラス名を 指定します。デフォルトでは StandardQueryCache になります。

例: classname.of.QueryCache

hibernate.cache.region_prefix 二次キャッシュの領域名の接頭辞です。

例: prefix

hibernate.cache.use_structured_entries 二次キャッシュに格納するデータを、人が理解しやすいフォーマットにします。

例: true|false

表 3.6. Hibernate トランザクションプロパティ

プロパティ名意味
hibernate.transaction.factory_class Hibernate Transaction APIと一緒に使われる TransactionFactory のクラス名です。 (デフォルトでは JDBCTransactionFactory です)。

例: classname.of.TransactionFactory

jta.UserTransaction アプリケーションサーバからJTA UserTransaction を取得するために JTATransactionFactory に使われるJNDI名です。

例: jndi/composite/name

hibernate.transaction.manager_lookup_classTransactionManagerLookup のクラス名です。 JTA環境において、JVMレベルのキャッシュを有効にするために必要です。

例: classname.of.TransactionManagerLookup

hibernate.transaction.flush_before_completion 有効の場合、トランザクションのcompletionフェーズの前に自動的に セッションをフラッシュします。内臓の自動セッションコンテキスト管理に適しています。 項2.5. 「コンテキスト上のセッション」を参照してください。

例: true | false

hibernate.transaction.auto_close_session 有効の場合、トランザクションのcompletionフェーズの後に セッションを自動的にクローズします。内臓の自動セッションコンテキスト管理に適しています。 項2.5. 「コンテキスト上のセッション」を参照してください。

例: true | false

表 3.7. その他のプロパティ

プロパティ名意味
hibernate.current_session_context_class 「現在の」Session のための(カスタム)戦略を提供します。 ビルトインストラテジーに関するその他の情報については 項2.5. 「コンテキスト上のセッション」を参照してください。

例: jta | thread | managed | custom.Class

hibernate.query.factory_class HQLパーサーの実装を選択します。

例: org.hibernate.hql.ast.ASTQueryTranslatorFactory or org.hibernate.hql.classic.ClassicQueryTranslatorFactory

hibernate.query.substitutions HQLとSQLのトークンをマッピングします。 (例えば、トークンは関数やリテラル名です)。

例: hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC

hibernate.hbm2ddl.autoSessionFactory を生成したときに、 自動的にスキーマDDLをDBに出力します。 create-drop の場合、 SessionFactory を クローズしたときに、データベーススキーマをドロップします。

例: validate | update | create | create-drop

hibernate.cglib.use_reflection_optimizer 実行時リフレクションの代わりのCGLIBの使用を有効にします (システムレベルのプロパティ) リフレクションはトラブルシューティングのときに役立つことがあります。 オプティマイザをオフにしているときでさえ、 Hibernateには必ずCGLIBが必要なことに注意してください。 このプロパティは hibernate.cfg.xml で設定できません。

例: true | false

3.4.1. SQL 方言(Dialect)

hibernate.dialect プロパティには、 使用するデータベースの正しい org.hibernate.dialect.Dialect のサブクラスを、 必ず指定すべきです。 しかし方言を指定すれば、Hibernateは上述したプロパティのいくつかについて、 より適切なデフォルト値を使います。 そうすれば、それらを手作業で設定する手間が省けます。

表 3.8. Hibernate SQL Dialects (hibernate.dialect)

RDBMSDialect
DB2org.hibernate.dialect.DB2Dialect
DB2 AS/400org.hibernate.dialect.DB2400Dialect
DB2 OS390org.hibernate.dialect.DB2390Dialect
PostgreSQLorg.hibernate.dialect.PostgreSQLDialect
MySQLorg.hibernate.dialect.MySQLDialect
MySQL with InnoDBorg.hibernate.dialect.MySQLInnoDBDialect
MySQL with MyISAMorg.hibernate.dialect.MySQLMyISAMDialect
Oracle (any version)org.hibernate.dialect.OracleDialect
Oracle 9i/10gorg.hibernate.dialect.Oracle9Dialect
Sybaseorg.hibernate.dialect.SybaseDialect
Sybase Anywhereorg.hibernate.dialect.SybaseAnywhereDialect
Microsoft SQL Serverorg.hibernate.dialect.SQLServerDialect
SAP DBorg.hibernate.dialect.SAPDBDialect
Informixorg.hibernate.dialect.InformixDialect
HypersonicSQLorg.hibernate.dialect.HSQLDialect
Ingresorg.hibernate.dialect.IngresDialect
Progressorg.hibernate.dialect.ProgressDialect
Mckoi SQLorg.hibernate.dialect.MckoiDialect
Interbaseorg.hibernate.dialect.InterbaseDialect
Pointbaseorg.hibernate.dialect.PointbaseDialect
FrontBaseorg.hibernate.dialect.FrontbaseDialect
Firebirdorg.hibernate.dialect.FirebirdDialect

3.4.2. 外部結合フェッチ

もしDBがANSIか、OracleかSybaseスタイルの外部結合をサポートしている場合、 outer join fetching は、DBのSQL発行回数を節約し パフォーマンスを良くします。(DB内でより多くの処理コストが発生します) 外部結合フェッチは、多対一、一対多、多対多、一対一のオブジェクト関連で グループオブジェクトを1つのSQLで SELECT します。

hibernate.max_fetch_depth プロパティの値を 0 にすると Outer join fetchingを すべて 無効にすることになります。 1 やそれ以上の値を設定すると、外部結合フェッチが有効になり、 一対一と多対一関連が fetch="join" としてマッピングされます。

See 項19.1. 「フェッチ戦略」 for more information.

3.4.3. バイナリストリーム

OracleはJDBCドライバとの間でやりとりされる byte 配列のサイズを制限します。 binaryserializable 型の大きなインスタンスを使いたければ、 hibernate.jdbc.use_streams_for_binary を有効にしてください。 ただし これはシステムレベルの設定だけです

3.4.4. 2次キャッシュとクエリーキャッシュ

hibernate.cache プロパティ接頭辞は Hibernateでプロセスやクラスタ二次キャッシュを使うとことを許可します。 項19.2. 「第2レベルキャッシュ」により多くの詳細があります。

3.4.5. クエリー言語の置き換え

hibernate.query.substitutions を使うことで、 新しいHibernateクエリトークンを定義できます。 例:

hibernate.query.substitutions true=1, false=0

これはトークン truefalse を、 生成されるSQLにおいて整数リテラルに翻訳します。

hibernate.query.substitutions toLowercase=LOWER

これはSQLの LOWER 関数の名前の付け替えを可能にします。

3.4.6. Hibernate 統計

hibernate.generate_statistics を有効にした場合、 動作しているシステムをチューニングするときに、SessionFactory.getStatistics() を経由して、Hibernateは便利な統計情報を出力します。 JMXを経由して統計情報を出力することも可能です。 Javadocの org.hibernate.stats パッケージ内の インターフェイスにはより多くの情報があります。

3.5. ロギング

HibernateはApache commons-logginを使って、さまざまなイベントをログとして 出力します。

commons-loggingサービスは(クラスパスに log4j.jar を含めれば)Apache Log4jに、 また(JDK1.4かそれ以上で実行させれば)JDK1.4 loggingに直接出力します。 Log4jは http://jakarta.apache.org からダウンロードできます。 Log4jを使うためには、クラスパスに log4j.properties ファイルを配置する必要があります。 例のプロパティファイルはHibernateと一緒に配布され、それは src/ ディレクトリにあります。

Hibernateのログメッセージに慣れることを強くおすすめします。 Hibernateのログは読みやすく、できる限り詳細になるように努力されています。 これは必須のトラブルシューティングデバイスです。 以下に重要なログのカテゴリを示します。

表 3.9. Hibernate ログカテゴリ

カテゴリ機能
org.hibernate.SQL実行したすべてのSQL(DDL)ステートメントをロギングします。
org.hibernate.typeすべてのJDBCパラメータをロギングします。
org.hibernate.tool.hbm2ddl実行したすべてのSQL(DDL)ステートメントをロギングします。
org.hibernate.pretty sessionに関連するすべてのエンティティ(最大20)のフラッシュ時間をロギングします。
org.hibernate.cacheすべての2次キャッシュの動作をロギングします。
org.hibernate.transactionトランザクションに関連する動作をロギングします。
org.hibernate.jdbcJDBCリソース取得をロギングします。
org.hibernate.hql.ast.AST HQLとSQLのASTのクエリーパースをロギングします。
org.hibernate.secureすべてのJAAS分析をロギングします。
org.hibernate すべてをロギングします。(情報が大量になりますが、トラブルシューティングには便利です)

Hibernateでアプリケーションを作成するときは、org.hibernate.SQL カテゴリの debug を常に有効にしておいたほうが良いでしょう。 代替方法として、hibernate.show_sql を有効にする方法があります。

3.6. NamingStrategy の実装

インターフェイス net.sf.hibernate.cfg.NamingStrategy を使うと データベースオブジェクトとスキーマ要素のための「命名標準」を指定できます。

Javaの識別子からデータベースの識別子を自動生成するためのルールや、 マッピングファイルで与えた「論理的な」カラムとテーブル名から 「物理的な」テーブルとカラム名を生成するためのルールを用意することができます。 この機能は繰り返しの雑音(例えば TBL_ プリフィックス)を取り除き、 マッピングドキュメントの冗長さを減らすことに役立ちます。 Hibernateが使うデフォルトの戦略はかなり最小限に近いものです。

マッピングを追加する前に Configuration.setNamingStrategy() を呼ぶことで 以下のように異なる戦略を指定することができます:

SessionFactory sf = new Configuration()
    .setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
    .addFile("Item.hbm.xml")
    .addFile("Bid.hbm.xml")
    .buildSessionFactory();

org.hibernate.cfg.ImprovedNamingStrategy は組み込みの戦略です。 これはいくつかのアプリケーションにとって有用な開始点となるかもしれません。

3.7. XML設定ファイル

もう1つの方法は hibernate.cfg.xml という名前のファイルで 十分な設定を指定する方法です。 このファイルは hibernate.properties ファイルの代わりとなります。 もし両方のファイルがあれば、プロパティが置き換えられます。

XML設定ファイルは初期設定で CLASSPATH に配置してください。 これが例です:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <!-- a SessionFactory instance listed as /jndi/name -->
    <!-- /jndi/nameのようにリストアップされたSessionFactoryインスタンス -->
    <session-factory
        name="java:hibernate/SessionFactory">

        <!-- properties -->
        <property name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="show_sql">false</property>
        <property name="transaction.factory_class">
            org.hibernate.transaction.JTATransactionFactory
        </property>
        <property name="jta.UserTransaction">java:comp/UserTransaction</property>

        <!-- mapping files -->
        <mapping resource="org/hibernate/auction/Item.hbm.xml"/>
        <mapping resource="org/hibernate/auction/Bid.hbm.xml"/>

        <!-- cache settings -->
        <class-cache class="org.hibernate.auction.Item" usage="read-write"/>
        <class-cache class="org.hibernate.auction.Bid" usage="read-only"/>
        <collection-cache collection="org.hibernate.auction.Item.bids" usage="read-write"/>

    </session-factory>

</hibernate-configuration>

見てのとおり、この方法の優位性は設定のためのマッピングファイル名を外出しにできることです。 Hibernateキャッシュをチューニングしなければならないのであれば、 hibernate.cfg.xml はより便利です。 hibernate.propertieshibernate.cfg.xml の どちらかを使えることを覚えておいてください。 二つは同じもので、違うところといえばXML構文を使うことの利点だけです。

XML設定を使うことで、Hibernateは以下のようにシンプルになります。

SessionFactory sf = new Configuration().configure().buildSessionFactory();

違うXML設定ファイルを使うこともできます。

SessionFactory sf = new Configuration()
    .configure("catdb.cfg.xml")
    .buildSessionFactory();

3.8. J2EEアプリケーションサーバとの統合

HibernateはJ2EE構造と統合するポイントをサポートしています。

  • コンテナ管理データソース:Hibernateは JNDIが提供し、コンテナが管理するJDBCコネクションを使用できます。 通常、JTA準拠の TransactionManagerResourceManager がトランザクション管理(CMT)、 特に様々なデータソースにまたがる分散トランザクションを扱います。 当然プログラムでトランザクション境界を指定できます(BMT)。 あるいは、記述したコードのポータビリティを保つために、 オプションのHibernateの Transaction APIを使いたくなるかもしれません。

  • 自動JNDIバインディング:HibernateはJNDIが立ち上がった後に SessionFactory を生成します。

  • JTAセッションバインディング : Hibernate Session のトランザクション境界はJTAトランザクションと同じになります。 単純に SessionFactory をJNDIからlookupして、 現在の Session を取得します。 JTAトランザクションが完了したときに、Hibernateが Session をフラッシュし、クローズします。 EJBデプロイメントディスクリプタの中に、トランザクション境界を宣言します。

  • JMXデプロイ: もしJMXが使用可能なアプリケーションサーバ(例えばJBOSS) がある場合、HibernateをMBeanとしてデプロイすることを選べます。 これは Configuration から SessionFactory を 生成するコードを無くすことができます。 コンテナは HibernateService を起動し、 サービスの依存を理想的に管理します(データソースはHibernateやその他が起動する前に 使用できるようにしなければなりません)。

環境に依存しますが、もし、アプリケーションサーバが"connection containment"の例外をスローするなら 設定のオプション hibernate.connection.aggressive_release をtrueにしてください。

3.8.1. トランザクション戦略設定

Hibernate Session APIは、アーキテクチャ内のシステムの管轄である あらゆるトランザクションに依存しません。 もしコネクションプールのJDBCを直接使いたい場合、JDBC APIから トランザクションを呼ぶことができます。 もし、J2EEアプリケーションサーバで動作させるなら、Bean管理トランザクションを使い、 必要に応じて UserTransaction をJTA APIから呼ぶことになるでしょう。

2つ(それ以上)の環境で互換性のあるコードを維持するために、オプションとして根本的なシステムを ラッピングするHibernate Transaction APIを推奨します。 Hibernate設定プロパティの hibernate.transaction.factory_class を設定することで ある特定の Transaction クラスのインスタンスを持つことができます。

3つの基本的な(既にある)選択を挙げます:

org.hibernate.transaction.JDBCTransactionFactory

データベース(JDBC)トランザクションに委譲します(デフォルト)

org.hibernate.transaction.JTATransactionFactory

もし、このコンテキスト(例えば、EJBセッションBeanメソッド)で進行中のトランザクションが存在する、もしくは 新しいトランザクションが開始されており、Bean管理トランザクションが使われている場合、 コンテナ管理トランザクションに委譲します。

org.hibernate.transaction.CMTTransactionFactory

コンテナ管理JTAトランザクションに委譲します

自分自身のトランザクション戦略(例えば、CORBAトランザクションサービス)を定義することもできます。

Hibernateのいくつかの機能(例えば、二次キャッシュ、JTAによるコンテキストセッション 等)は 管理された環境の中のJTA TransactionManager へのアクセスを要求します。 J2EEがひとつのメカニズムに規格化されていないので、 アプリケーションサーバにおいて、Hibernateが TransactionManager のリファレンス を取得する方法を明確にする必要があります。

表 3.10. JTA トランザクションマネージャ

Transaction FactoryApplication Server
org.hibernate.transaction.JBossTransactionManagerLookupJBoss
org.hibernate.transaction.WeblogicTransactionManagerLookupWeblogic
org.hibernate.transaction.WebSphereTransactionManagerLookupWebSphere
org.hibernate.transaction.WebSphereExtendedJTATransactionLookupWebSphere 6
org.hibernate.transaction.OrionTransactionManagerLookupOrion
org.hibernate.transaction.ResinTransactionManagerLookupResin
org.hibernate.transaction.JOTMTransactionManagerLookupJOTM
org.hibernate.transaction.JOnASTransactionManagerLookupJOnAS
org.hibernate.transaction.JRun4TransactionManagerLookupJRun4
org.hibernate.transaction.BESTransactionManagerLookupBorland ES

3.8.2. SessionFactory のJNDIへの登録

JNDIに登録したHibernate SessionFactory は単純に ファクトリをルックアップし、新しい Session を作ります。 これはJNDIに登録された Datasource には関連せず、 お互いにシンプルにこれらの登録を使うことに注意してください。

もし SessionFactory をJNDIネームスペースに登録したい場合、 特別な名前(例えば、 java:hibernate/SessionFactory )を hibernate.session_factory_name プロパティに使ってください もしこのプロパティを省略した場合、 SessionFactory は JNDIに登録されません。(これはTomcatのようなデフォルト実装でJNDIが読みより専用の環境の場合特に便利です。)

SessionFactory をJNDIに登録するとき、Hibernateは hibernate.jndi.url の値を使用し、hibernate.jndi.class をイニシャルコンテキストとして具体化します。 もし何も設定しない場合は、デフォルトの InitialContext を使用します。

cfg.buildSessionFactory() をコール後 Hibernateは自動的に SessionFactory をJNDIに配置します。 HibernateService と一緒にJMXデプロイメントを使わない限り、 これはこの呼び出しをアプリケーション内の何らかのスタートアップコード(もしくはユーティリティクラス) に配置しなければならないことを意味します。(後で議論します)

もしJNDI SessionFactory を使う場合、EJBや他のクラスは JNDIルックアップを使って SessionFactory を取得します。

管理された環境では SessionFactory をJNDIにバインドし、 そうでなければ static シングルトンを使うことを推奨します。 こういった詳細からアプリケーションコードを保護するために、 HibernateUtil.getSessionFactory() のようなヘルパークラスの中に、 SessionFactory をルックアップするコードを隠すことを推奨します。 このようなヘルパークラスはHibernateを開始する便利な手段でもあります。 —1章を参照してください。

3.8.3. JTAによる現在のセッションコンテキストマネージメント

もっとも簡単に Session とトランザクションを扱う方法は、 Hibernateが自動的に「現在の」 Session を管理することです。 項2.5. 「コンテキスト上のセッション」 の説明を参照してください。 もし 「JTA」 セッションコンテキストを使った上で、 現在のJTAトランザクションとHibernate Session が関連していない場合は、 最初に sessionFactory.getCurrentSession() をコールし、 JTAトランザクションとの関連付けを行ってください。 「JTA」 コンテキストの getCurrentSession() を 通じて取得した Session は、トランザクションが完了する前に 自動的にフラッシュし、完了した後には自動的にクローズします。 また、各ステートメント後にJDBCコネクションを積極的にリリースします。 これによりJTAトランザクションのライフサイクルで Session を管理することができ、 ユーザーのコードからそのような管理をするコードを排除できます。 UserTransaction を通じてJTAをプログラムで管理することができます。 または、(ポータブルなコードであれば)Hibernate Transaction APIを トランザクション境界として使うこともできます。 EJBコンテナを使うときは、CMTによる宣言的トランザクション境界が好ましいです。

3.8.4. JMXデプロイメント

SessionFactory をJNDIから取得するためには cfg.buildSessionFactory() 行をどこかで実行していなければなりません。 あなたはこれを、static 初期化ブロック内( HibernateUtil のような)か managed service としてHibernateをデプロイするか、どちらかで実行できます。

JBOSSのようなJMXの機能でアプリケーションサーバにデプロイするために org.hibernate.jmx.HibernateService を使って、配置します。 実際のデプロイメントと設定はベンダー特有です。 ここで例としてJBOSS 4.0.x用の jboss-service.xml を示します。

<?xml version="1.0"?>
<server>

<mbean code="org.hibernate.jmx.HibernateService"
    name="jboss.jca:service=HibernateFactory,name=HibernateFactory">

    <!-- Required services -->
    <depends>jboss.jca:service=RARDeployer</depends>
    <depends>jboss.jca:service=LocalTxCM,name=HsqlDS</depends>

    <!-- Bind the Hibernate service to JNDI -->
    <attribute name="JndiName">java:/hibernate/SessionFactory</attribute>

    <!-- Datasource settings -->
    <attribute name="Datasource">java:HsqlDS</attribute>
    <attribute name="Dialect">org.hibernate.dialect.HSQLDialect</attribute>

    <!-- Transaction integration -->
    <attribute name="TransactionStrategy">
        org.hibernate.transaction.JTATransactionFactory</attribute>
    <attribute name="TransactionManagerLookupStrategy">
        org.hibernate.transaction.JBossTransactionManagerLookup</attribute>
    <attribute name="FlushBeforeCompletionEnabled">true</attribute>
    <attribute name="AutoCloseSessionEnabled">true</attribute>

    <!-- Fetching options -->
    <attribute name="MaximumFetchDepth">5</attribute>

    <!-- Second-level caching -->
    <attribute name="SecondLevelCacheEnabled">true</attribute>
    <attribute name="CacheProviderClass">org.hibernate.cache.EhCacheProvider</attribute>
    <attribute name="QueryCacheEnabled">true</attribute>

    <!-- Logging -->
    <attribute name="ShowSqlEnabled">true</attribute>

    <!-- Mapping files -->
    <attribute name="MapResources">auction/Item.hbm.xml,auction/Category.hbm.xml</attribute>

</mbean>

</server>

このファイルは META-INF ディレクトリに配置され、 JARファイルを拡張した .sar (service archive)でパッケージ化されます。 同様にHibernateパッケージも必要です。また、Hibernateはサードパーティのライブラリも要求します。 コンパイルした永続化クラスとそのマッピングファイルも同様にアーカイブ(.sarファイル)に入れます。 エンタープライズbean(通常はセッションbean)は自身のJARファイルを保持しますが、 1回で(ホット)デプロイ可能なユニットのためにメインサービスアーカイブとしてこのEJB JARファイルをインクルードする ことができます。JBossアプリケーションサーバのドキュメントにJXMサービスと EJBデプロイメントのより多くの情報があります。