Hibernateは、多くのさまざまな環境で使えるように設計されているので、 設定パラメータがたくさん用意されています。 さいわい、ほとんどのパラメータには適当なデフォルト値が定められており、 またさまざまなオプションを示す hibernate.properties ファイルのサンプルが付属しています。 普通はクラスパスにこのファイルを置いて、カスタマイズするだけで十分のはずです。
net.sf.hibernate.cfg.Configuration のインスタンスは、 アプリケーションのJava型からリレーショナル・データベースへのマッピングのセットを表します。 Configuration は、 (更新不能の)SessionFactory をビルドするために使います。 マッピングはいろいろなXMLマッピング・ファイルからコンパイルされます。
Configuration インスタンスは、直接インスタンス化して取得できます。 これは(クラスパスにおいて)2つのXML設定ファイルで定義されたマッピングからの データストアの設定例です:
Configuration cfg = new Configuration() .addFile("Item.hbm.xml") .addFile("Bid.hbm.xml");
もう1つの(ときどきはより良い)方法は、getResourceAsStream() を使って マッピング・ファイルをロードする方法です。
Configuration cfg = new Configuration() .addClass(org.hibernate.auction.Item.class) .addClass(org.hibernate.auction.Bid.class);
するとHibernateはクラスパスで、 /org/hibernate/autcion/Item.hbm.xml と /org/hibernate/autcion/Bid.hbm.xml という名前のマッピング・ファイルを探します。 この方法を使えば、ファイル名をハード・コーディングしなくてすみます。
Configuration でも、いろいろなオプションのプロパティを指定します:
Properties props = new Properties(); ... Configuration cfg = new Configuration() .addClass(org.hibernate.auction.Item.class) .addClass(org.hibernate.auction.Bid.class) .setProperties(props);
Configuration は設定時のオブジェクトとして考えられており、 SessionFactory が作成された後は捨てられるものと意図されています。
すべてのマッピングが Configuration によって構文解析されたとき、 アプリケーションは Session インスタンスのファクトリを 取得しなければなりません。 このファクトリはすべてのアプリケーション・スレッドで共有されるものと考えられています:
SessionFactory sessions = cfg.buildSessionFactory();
しかしHibernateは、アプリケーションが SessionFactory を 複数インスタンス化することを許しています。 これは複数のデータベースをを使うときに役に立ちます。
SessionFactory は、 ユーザが用意したJDBCコネクションで Session をオープンできます。 この設計により、アプリケーションが欲しいときにいつでも、 JDBCコネクションを取得できます:
java.sql.Connection conn = datasource.getConnection(); Session session = sessions.openSession(conn); // データにアクセスする作業をいくつか行います
アプリケーションは同じJDBCコネクションで、 2つの同時並行 Session をオープンしないように気を付けなければいけません。
Alternatively, you can have the SessionFactory open connections for you. The SessionFactory must be provided with JDBC connection properties in one of the following ways: もう1つの方法として、SessionFactory にコネクションをオープンさせることもできます。 SessionFactory には以下の方法のどれか1つを使い、 JDBCコネクション・プロパティを与えなければいけません:
java.util.Properties のインスタンスを Configuration.setProperties() に渡す。
hibernate.properties をクラスパスのルート・ディレクトリに置く。
java -Dproperty=value を使い、 System プロパティを設定する。
hibernate.cfg.xml に <property> 要素を含める(後で議論します)。
この方法を使えば、以下のように Session のオープンが簡単になります:
Session session = sessions.openSession(); // 新しいSessionをオープンします // データにアクセスする作業をいくつか行います。JDBCコネクションが要求に応じて使われます。
すべてのHibernateプロパティの名前と意味は、 net.sf.hibernate.cfg.Environment クラスで定義されています。 それでは、JDBCコネクションの最も重要な設定について述べていきます。
以下のプロパティを設定すれば、Hibernateは java.sql.DriverManager を使って、 コネクションを取得(そしてプール)します:
表 3.1. Hibernate JDBC プロパティ
プロパティ名 | 目的 |
---|---|
hibernate.connection.driver_class | JDBCドライバ・クラス |
hibernate.connection.url | JDBC URL |
hibernate.connection.username | データベースのユーザ |
hibernate.connection.password | データベースのユーザのパスワード |
hibernate.connection.pool_size | プールするコネクションの最大数 |
Hibernate独自のコネクション・プーリング・アルゴリズムは、かなり初歩的なものです。 これはHibernateを始める手助けのためのものであり、 製品のシステムでのしようを意図していません し、 パフォーマンス・テストへの使用でさえ意図していません。 最高のパフォーマンスと安定性を得るためには、サードパーティのプールを使ってください。 そしてコネクション・プールの設定で、 hibernate.connection.pool_size プロパティを置き換えてください。
C3P0はオープン・ソースのJDBCコネクション・プールで、Hibernateと一緒に配布されています。 これは lib ディレクトリにあります。 hibernate.c3p0.* プロパティを設定すれば、 Hibernateはコネクション・プールのために、組み込みの C3P0ConnectionProvider を使います。 また、Apache DBCPとProxoolも組み込みでサポートしています。 DBCPConnectionProvider を有効にするには、 hibernate.dbcp.* プロパティ (DBCPコネクション・プール・プロパティ)を設定しなければいけません。 hibernate.dbcp.ps.* (DBCPステートメント・キャッシュ・プロパティ)が設定されれば、 Prepared statementのキャッシュが有効になります(非常におすすめです)。 これらのプロパティについては、Apache commons-poolのドキュメントを参照してください。 またProxoolを使いたければ、hibernate.proxool.* プロパティを設定してください。
以下は、C3P0を使った例です:
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 = net.sf.hibernate.dialect.PostgreSQLDialect
アプリケーション・サーバの内部で使うために、 HibernateはJNDIで登録された javax.sql.Datasource からコネクションを取得できます。 以下のプロパティを設定してください:
表 3.2. Hibernateデータソース・プロパティ
プロパティ名 | 目的 |
---|---|
hibernate.connection.datasource | データソースのJNDI名 |
hibernate.jndi.url | JNDIプロバイダのURL(オプション) |
hibernate.jndi.class | InitialContextFactory のクラス(オプション) |
hibernate.connection.username | データベースのユーザ(オプション) |
hibernate.connection.password | データベースのユーザのパスワード(オプション) |
以下は、JNDIデータソースが提供したアプリケーション・サーバを使った例です:
hibernate.connection.datasource = java:/comp/env/jdbc/MyDB hibernate.transaction.factory_class = \ net.sf.hibernate.transaction.JTATransactionFactory hibernate.transaction.manager_lookup_class = \ net.sf.hibernate.transaction.JBossTransactionManagerLookup hibernate.dialect = \ net.sf.hibernate.dialect.PostgreSQLDialect
JNDIデータソースから取得されたJDBCコネクションは、 アプリケーション・サーバのコンテナ管理トランザクションに自動的に登録されます。
任意のコネクション・プロパティは、 "hibernate.connnection" の後にプロパティ名を続けることで与えられます。 例えば hibernate.connnection.charSet を使い、 charSet を指定できます。
net.sf.hibernate.connection.ConnectionProvider を実装することで、 JDBCコネクションを取得するための独自のプラグイン戦略を定義できます。 また hibernate.connection.provider_class の設定によって、 カスタムの実装を選べます。
Hibernateの実行時の振る舞いを制御するために使うプロパティが、他にもたくさんあります。 すべてがオプションで、適当なデフォルト値が設定されています。
システム・レベルのプロパティは java -Dproperty=value で設定するか hibernate.properties で定義し、 Configuration に渡される Properties では設定できません。
表 3.3. Hibernate設定プロパティ
プロパティ名 | 目的 |
---|---|
hibernate.dialect |
Hibernate Dialect のクラス名。
プラットフォーム依存の機能を有効にします。
例 full.classname.of.Dialect |
hibernate.default_schema |
生成されるSQLにおいて、与えられるスキーマ/テーブルスペースで
非修飾のテーブル名を修飾します。
例 SCHEMA_NAME |
hibernate.session_factory_name |
作成された後、SessionFactory がJNDIにおいて
自動的にこの名前にバインドされます。
例 jndi/composite/name |
hibernate.use_outer_join |
アウター・ジョインによるフェッチを有効にします。推奨されません。
max_fetch_depth を使ってください。
例 true | false |
hibernate.max_fetch_depth |
末端が1の関連(one-to-one, many-to-one)に対して、
アウター・ジョインのツリーの「深さ」の最大値を設定します。
0 と指定すると、
デフォルトのアウター・ジョインによるフェッチが無効になります。
例 おすすめは 0 から 3 の間の値 |
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 に設定してください
(普通はこのオプションをオンにしても安全です)。
すると自動的にバージョン付けされたデータに対して、
HibernateはバッチのDMLを使います。
デフォルトは false です。
例 true | false |
hibernate.jdbc.use_scrollable_resultset |
HibernateによるJDBC2スクローラブル・リザルトセットを有効にします。
このプロパティはユーザが用意するJDBCコネクションを使うときにだけ必要で、
そうでなければHibernateはコネクション・メタデータを使います。
例 true | false |
hibernate.jdbc.use_streams_for_binary | binary や serializable 型をJDBCに書き込んだり
読み込んだりするときに、ストリームを使います
(システム・レベルのプロパティです)。
例 true | false |
hibernate.jdbc.use_get_generated_keys |
挿入の後にネイティブに生成されたキーを復元するための
PreparedStatement.getGeneratedKeys() の使用を有効にします。
これはJDBC3+ドライバとJRE1.4+を必要とし、
もしHibernateの識別子ジェネレータに問題が発生するようならfalseに設定してください。
デフォルトではコネクション・メタデータを使いドライバの能力を決定するようにしてください。
例 true | false |
hibernate.cglib.use_reflection_optimizer |
実行時リフレクションの代わりのCGLIBの使用を有効にします
(システム・レベルのプロパティ)
リフレクションはトラブルシューティングのときに役立つことがあります。
オプティマイザをオフにしているときでさえ、
Hibernateには必ずCGLIBが必要なことに注意してください。
このプロパティは hibernate.cfg.xml で設定できません。
例 true | false |
hibernate.jndi.<propertyName> | propertyName プロパティを、 JNDI InitialContextFactory に渡します。 |
hibernate.connection.isolation |
JDBCトランザクション分離レベルを設定します。
妥当な値を調べるためには java.sql.Connection をチェックしてください。
しかし使用するデータベースが、すべての分離レベルをサポートしているとは限りません。
例 1, 2, 4, 8 |
hibernate.connection.<propertyName> | propertyName JDBCプロパティを DriverManager.getConnection() に渡します。 |
hibernate.connection.provider_class |
カスタム ConnectionProvider のクラス名。
例 classname.of.ConnectionProvider |
hibernate.cache.provider_class |
カスタム CacheProvider のクラス名。
例 classname.of.CacheProvider |
hibernate.cache.use_minimal_puts |
書き込みを最小限にするために、第2レベル・キャッシュの操作を最適化します。
その代わりに、読み込みがより頻繁に発生するようになります
(クラスタ・キャッシュに役に立ちます)。
例 true|false |
hibernate.cache.use_query_cache |
クエリのキャッシュを有効にします。
個々のクエリはまだキャッシャブルに設定されなければなりません。
例 true|false |
hibernate.cache.query_cache_factory |
カスタム QueryCache インターフェイスのクラス名。
デフォルトは組み込みの StandardQueryCache です。
例 classname.of.QueryCache |
hibernate.cache.region_prefix |
第2レベル・キャッシュの領域の名前に使うプリフィックス。
例 prefix |
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_class | TransactionManagerLookup のクラス名。
JTA環境において、JVMレベルのキャッシュを有効にするために必要です。
例 classname.of.TransactionManagerLookup |
hibernate.query.substitutions |
HibernateクエリのトークンからSQLのトークンへのマッピング
(例えばトークンは関数やリテラルの名前かもしれません)。
例 hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC |
hibernate.show_sql |
すべてのSQL文をコンソールに書き出します。
例 true | false |
hibernate.hbm2ddl.auto | SessionFactory が作成されるとき、
自動的にスキーマDDLをデータベースにエクスポートします。
create-drop と指定されると、
SessionFactory が明示的にクローズされるときに
データベース・スキーマがドロップされます。
例 update | create | create-drop |
hibernate.dialect プロパティには、 使用するデータベースの正しい net.sf.hibernate.dialect.Dialect のサブクラスを、 必ず指定すべきです。 もし native または sequence 主キー生成や (例えば Session.lock() や Query.setLockMode() で) 悲観的ロックを使いたいのでなければ、厳密に言うと必須ではありません。 しかし方言を指定すれば、Hibernateは上述したプロパティのいくつかについて、 より適切なデフォルト値を使います。 そうすれば、それらを手作業で設定する手間が省けます。
表 3.4. Hibernate SQL方言 (hibernate.dialect)
RDBMS | 方言 |
---|---|
DB2 | net.sf.hibernate.dialect.DB2Dialect |
DB2 AS/400 | net.sf.hibernate.dialect.DB2400Dialect |
DB2 OS390 | net.sf.hibernate.dialect.DB2390Dialect |
PostgreSQL | net.sf.hibernate.dialect.PostgreSQLDialect |
MySQL | net.sf.hibernate.dialect.MySQLDialect |
Oracle (any version) | net.sf.hibernate.dialect.OracleDialect |
Oracle 9/10g | net.sf.hibernate.dialect.Oracle9Dialect |
Sybase | net.sf.hibernate.dialect.SybaseDialect |
Sybase Anywhere | net.sf.hibernate.dialect.SybaseAnywhereDialect |
Microsoft SQL Server | net.sf.hibernate.dialect.SQLServerDialect |
SAP DB | net.sf.hibernate.dialect.SAPDBDialect |
Informix | net.sf.hibernate.dialect.InformixDialect |
HypersonicSQL | net.sf.hibernate.dialect.HSQLDialect |
Ingres | net.sf.hibernate.dialect.IngresDialect |
Progress | net.sf.hibernate.dialect.ProgressDialect |
Mckoi SQL | net.sf.hibernate.dialect.MckoiDialect |
Interbase | net.sf.hibernate.dialect.InterbaseDialect |
Pointbase | net.sf.hibernate.dialect.PointbaseDialect |
FrontBase | net.sf.hibernate.dialect.FrontbaseDialect |
Firebird | net.sf.hibernate.dialect.FirebirdDialect |
データベースがANSIやOracleスタイルのアウター・ジョインをサポートしていれば、 (可能な限りデータベース自体に仕事を任せ) データベースとのやりとりの回数を制限する アウター・ジョインによるフェッチ によって、 パフォーマンスを改善できるかもしれません。 アウター・ジョインにより、many-to-one, one-to-many, one-to-one関連で接続されたオブジェクトのグラフを、 SQL SELECT 1つだけで復元できます。
デフォルトではオブジェクトの取得は、リーフ・オブジェクト、 コレクション、プロキシ・オブジェクト、循環が発生するところで終わります。
特定の関連 に対しては、 XMLマッピングで outer-join 属性を設定することで、 フェッチを有効または無効に(そしてデフォルトの振る舞いをオーバーライド)できます。
hibernate.max_fetch_depth プロパティを 0 に設定することで、 アウター・ジョインによるフェッチを グローバルに 無効にできます。 1 以上に設定すると、すべてのone-to-oneとmany-to-one関連に対して、 アウター・ジョインによるフェッチが可能になります。 これらのアウター・ジョインは、デフォルトでは auto に設定されています。 しかし特定の関連それぞれについて明示的に宣言しなければ、 one-to-many関連とコレクションはアウター・ジョインでフェッチされません。 この振る舞いは、Hibernateクエリで実行時にオーバーライドすることもできます。
OracleはJDBCドライバとの間でやりとりされる byte 配列のサイズを制限します。 binary や serializable 型の大きなインスタンスを使いたければ、 hibernate.jdbc.use_streams_for_binary を有効にしてください。 ただし これはJVMレベルの設定だけです 。
インターフェイス net.sf.hibernate.cache.CacheProvider を実装すると、 JVMレベル(またはクラスタ)第2レベル・キャッシュ・システムを統合できます。 hibernate.cache.provider_class を設定すると、 カスタムの実装を選べます。
Hibernate Transaction APIを使いたければ、 プロパティ hibernate.transaction.factory_class を設定して、 Transaction インスタンスのためのファクトリ・クラスを 指定しなければなりません。 Transaction APIは、ベースとなるトランザクション機構を隠蔽し、 管理された環境と管理されていない環境の両方で、Hibernateのコードの実行を可能にします。
標準的な2つの(組み込みの)選択肢があります:
データベース(JDBC)トランザクションに委譲します(デフォルト)
JTAに委譲します(既存のトランザクションが実行中なら、 Session はそのコンテキストで動作します。 そうでなければ、新しいトランザクションを開始します。)
独自のトランザクション戦略も定義できます (例えばCORBAトランザクション・サービスのための戦略)。
JTA環境で更新不能のデータのJVMレベル・キャッシュを使いたければ、 これはJ2EEに対して標準化されていないため、 JTA TransactionManager を取得するための戦略を 指定しなければいけません:
表 3.5. JTAトランザクション・マネージャ
トランザクション・ファクトリ | アプリケーション・サーバ |
---|---|
net.sf.hibernate.transaction.JBossTransactionManagerLookup | JBoss |
net.sf.hibernate.transaction.WeblogicTransactionManagerLookup | Weblogic |
net.sf.hibernate.transaction.WebSphereTransactionManagerLookup | WebSphere |
net.sf.hibernate.transaction.OrionTransactionManagerLookup | Orion |
net.sf.hibernate.transaction.ResinTransactionManagerLookup | Resin |
net.sf.hibernate.transaction.JOTMTransactionManagerLookup | JOTM |
net.sf.hibernate.transaction.JOnASTransactionManagerLookup | JOnAS |
net.sf.hibernate.transaction.JRun4TransactionManagerLookup | JRun4 |
net.sf.hibernate.transaction.BESTransactionManagerLookup | Borland ES |
JNDIバインドのHibernate SessionFactory は、 ファクトリの検索と新しい Session の検索を単純化できます。
SessionFactory をJNDI名前空間にバインドさせたければ、 プロパティ hibernate.session_factory_name を使い、 名前(例 java:comp/env/hibernate/SessionFactory)を指定します。 このプロパティを設定しなければ、SessionFactory はJNDIにバインドされません。 これはread-onlyのJNDIデフォルト実装の環境において特に役に立ちます。例 Tomcat)
SessionFactory をJNDIにバインドさせるとき、 Hibernateはイニシャル・コンテキストをインスタンス化するために hibernate.jndi.url, hibernate.jndi.class の値を使います。 それらの値が指定されなければ、デフォルトの InitialContext が使われます。
JNDIを使うことにしたなら、JNDIルック・アップを使い、 EJBや他のユーティリティ・クラスは SessionFactory を取得できます。
HibernateはApache commons-loggingを使い、いろいろなイベントをログに取ります。
commons-loggingサービスは(クラスパスに log4j.jar を含めれば)Apache Log4jに、 また(JDK1.4かそれ以上で実行させれば)JDK1.4 loggingに直接出力します。 Log4jは http://jakarta.apache.org からダウンロードできます。 Log4jを使うためには、クラスパスに log4j.properties ファイルを配置する必要があります。 例のプロパティ・ファイルはHibernateと一緒に配布され、それは src/ ディレクトリにあります。
Hibernateのログ・メッセージになれることを強くおすすめします。 Hibernateのログは読みにくくならずにできる限り詳細になるように努力されています。 これは必須のトラブルシューティング・デバイスです。 また上で述べたようにSQLロギングを有効にすることを忘れないでください (hibernate.show_sql)。 パフォーマンスの問題を探すときこれが最初のステップとなります。
インターフェイス 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();
net.sf.hibernate.cfg.ImprovedNamingStrategy is a built-in strategy that might be a useful starting point for some applications. net.sf.hibernate.cfg.ImprovedNamingStrategy は組み込みの戦略です。 これはいくつかのアプリケーションにとって有用な開始点となるかもしれません。
もう1つの方法は hibernate.cfg.xml という名前のファイルで 十分な設定を指定する方法です。 このファイルは hibernate.properties ファイルの代わりとなります。 もし両方のファイルがあれば、プロパティが置き換えられます。
XML設定ファイルはデフォルトで CLASSPATH に配置されることを期待されています。 これが例です:
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd"> <hibernate-configuration> <!-- /jndi/nameのようにリストアップされたSessionFactoryインスタンス --> <session-factory name="java:comp/env/hibernate/SessionFactory"> <!-- プロパティ --> <property name="connection.datasource">my/first/datasource</property> <property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property> <property name="show_sql">false</property> <property name="use_outer_join">true</property> <property name="transaction.factory_class"> net.sf.hibernate.transaction.JTATransactionFactory </property> <property name="jta.UserTransaction">java:comp/UserTransaction</property> <!-- マッピング・ファイル --> <mapping resource="org/hibernate/auction/Item.hbm.xml"/> <mapping resource="org/hibernate/auction/Bid.hbm.xml"/> </session-factory> </hibernate-configuration>
Hibernateの設定は以下のように簡単になります。
SessionFactory sf = new Configuration().configure().buildSessionFactory();
また以下のようにすると異なるXML設定ファイルを使うことができます。
SessionFactory sf = new Configuration() .configure("/my/package/catdb.cfg.xml") .buildSessionFactory();