Javaベースのオブジェクト関係(O/R)マッピングフレームワーク「Hibernate」(リンク)のバージョン3.3(リンク)が先日リリースされた。InfoQは、今回のリリースの詳細とHibernateに追加される新機能について、プロジェクトリーダーのSteve Ebersole氏(リンク)に聞いた。
Hibernate 3.3の主な新機能には、以下が含まれる。
- 再設計されたモジュール式のJAR - 大型のJARが1つあるのではなく、現在では粒度の細かいJARが多数存在します -- これによりユーザは、依存性をたやすく把握でき、最小化も簡単になり、また、組織は欲しくない部分を入れることなく、カスタマイズしたHibernateのデプロイメントを構築できます
- Mavenベースのビルド - Hibernateは現在、Apache Maven(リンク)ビルドシステムを使って構築されています
- キャッシングSPIの刷新 - フィードバックに基づき、異なるキャッシュ域の特性をいっそうきめ細かく制御可能にすべく、キャッシュシステムをリファクタリングしました
- JBoss Cache 2.x(参考資料)の統合 - 新しいキャッシングSPIに基づき、追加設定することなく、JBoss Cache 2.xの統合をすぐに利用できます
Ebersole氏は、新しいキャッシュシステムとJBoss Cache統合についても、さらに詳しく説明している。
SPIの主な変更では、特定の目的を意図したキャッシュ域を構築する機能を中心に据えています。Hibernateは基本的に4つの明確な目的のためにキャッシュ域を必要としますが、その4つとは、エンティティデータ、コレクションデータ、クエリ結果、更新タイムスタンプです。これまでのSPIでは、こうした異なるタイプをひとつのやり方で処理しようとしていました。保存されているデータの特性にかかわらず、データのキャッシングを根本的に普遍的な方法で処理しようとしたのです。しかし実際は、キャッシング・インテグレータがそうした異なる特性を把握していなければならないことが多々ありました。たとえば、クラスタ化したキャッシュではおそらく、エンティティデータとコレクションデータには同期無効化を使い、クエリと更新タイムスタンプのキャッシュ域にはローカルオンリーのモードを使用するのが道理にかなっているでしょう。これまでのSPIでは、域名称に基づいて小ずるい仮定をしない限り、こうした組み合せは不可能でした。新しいSPIでは、この区別を明白にしています。ですから、たとえば「buildEntityRegion」や「buildCollectionRegion」といったメソッドがあり、そのため、キャッシング・インテグレータは、所定の域が保持すべきデータタイプを識別でき、適切に構成したキャッシュ/域を構築できます。
JBossCache 2.xの統合は現在のところ、新しいSPIを直接使用している唯一のキャッシングの統合です(残りは新SPIと、現在では非推奨になっている旧SPI間でブリッジを使っています)。ですから、先ほど申し上げた区別をフルに活用し、ユーザは様々な域に異なった動作を定義できるようになります。JBossCache 2.xでは、Hibernateユースケースの利益になるという点で、JBossCache 1.xに2つの具体的な改良を加えています。ひとつめは、「putForExternalRead」プロセスの追加です。JBossCache 1.xでは、データベースからデータを読み込んでJBossCache域にそのデータを入れるとき、パフォーマンスの問題が起きたり、デッドロックさえ発生したりしていました。何が起きるかというと、全体的なユースケースのセマンティクスでは読み込みロックを是認しているにもかかわらず、データの読み込みだけを試みていたノード上に、JBossCacheが書き込みロックを確保しようとしていたのです。そうするとその書き込みロックは、他のトランザクションをブロックします。JBossCache 2.xは特にこのユースケース向けに設計したメソッドを導入しており、統合によってそのメソッドが活用されます。
Hibernateの使用法から見たJBossCache 2.xにおけるもう1つの重要な改良点は、クラスタ全体の無効化管理が優れているという点で、特にオプティミスティック・ロッキングの管理に優れています。最も大きな変更点は、無効化されたエンティティ向けに「tombstone」(削除記録)を確実に残しておくことで、そのエンティティをキャッシュに書こうと次に試みた際には、無効化されたバージョンが判明しており、バージョンの検査が適切に実施されるということです。Hibernateに関して無効化は重要ですが、その理由は、クラスタ化されたエンティティキャッシュを処理する最も効率的な方法だからです。
もう1つ論じられた分野は、他のJPA実装がいかにHibernateに影響を与えてきたか、である。
TopLink/OpenJPAを最初に検討していた時、たまたまHibernateのBytecodeProviderサポートでも作業をしていました。クラスを動的にインスツルメント化するためにJVMエージェントを使うアイデアが非常に気に入ったのですが、その理由は、JVMエージェントは別個のビルドタイム・ステップを必要とせず、ロードされるからです。まだHibernateでは日の目を見ていませんが、Hibernate 4.0ではJDk 1.4をサポートしなくなるので、4.0での実現を計画しています。
最近のOSGi人気の高まりに伴って起きた問題に、OSGiコンテナ内でHibernateを動作させると時々発生する不具合(リンク)がある。Ebersole氏によると、SessionFactoryを動的に再定義する機能については現在調査中で、クラスローディングの問題についても承知しているそうである。しかしながら、氏の指摘によると、この2つの問題に関するhibernate-devの電子メールは1通も存在せず、JIRAの議題としては多少(リンク)論じられただけであり、そして氏の知る限り、Hibernate開発チームのメンバーでこの件に関して働きかけを受けた者は1人もいない。Ebersole氏はこの問題、さらにはHibernateで発生するその他のあらゆる問題の解決に向けてコミュニティと一丸となって取り組みたいと熱望している。また、OSGi関係者もしくはOSGiの心得のある人物にHibernateのOSGi相互運用性を向上させる手助けをしてもらえるなら、あるいは、そうした互換性の取り組みに何が必要かを調査する援助だけでもしてもらえるなら、氏宛てに連絡を入れて欲しいそうである。
Hibernateの将来の計画について、Ebersole氏は次のように述べている。
3.3.0 GAがリリースされたので、3.3.xについてJIRAで未解決になっている問題を一致団結して片付ける時期がやってきます。
すでに、3.4と4.0の両方の計画に取り組んでいます。通常は将来のロードマップを論じることはありませんが、3.4の作業が始まり、機能一式がすでに大筋で決定しているので、少々お話ししてもいい気分になっています。大きな焦点となっているのが、クラスタ化されたフェイルオーバーのシナリオにおけるHibernateの使用に関して、パフォーマンスとリソース活用を改良することです。もう1つは「フェッチプロファイル」の導入で、メタデータで名前付きフェッチ戦略を設定し、ランタイム時にSessionでそうしたプロファイルを動的に有効化できます。いずれにせよ、3.4ではこうしたものが目玉となります。