SeamFramework.org Community Documentation

- 前のページ
- 次のページ

## 第29章 Hibernate Search

## 29.1. はじめに

Apache Lucene™ のような全文検索エンジンは、最適な問い合わせと検索結果を取得できるとても強力な技術です。検索エンジンに Apache Lucene を使用している Hibernate Searchは、いくつかのアノテーションを追加したドメインモデルをインデックスし、データベースとインデックスの同期を解決し、さらに全文検索の問い合わせにしたがった検索結果のオブジェクトを取得します。しかしながら、テキストのインデックスにかかわるようなドメインオブジェクトモデルを取り扱う検索を行ったときに、不整合が発生することがあることも覚えておいてください。(インデックスを最新の状態に維持すると、インデックスの構造とドメインモデルが合わなくなるので、問い合わせで不整合が発生します) しかし、検索スピードと効率面を考えれば、これらの制約を補ってあまりあるメリットがあります。

Hibernate Search は、よりよく、そしてできるだけ自然に JPA と Hibernate を統合するために設計されました。これを自然な形で拡張させるものとして、JBoss Seam は Hibernate Searchの統合を提供しています。

Hibernate Search プロジェクトについて明確に記している Hibernate Seachの文書 を参照してください。

## 29.2. 設定

Hibernate Search は、`META-INF/persistence.xml` または `hibernate.cfg.xml` のいずれかのファイルで設定します。

Hibernate Search の設定は、ほとんどの設定パラメータにおいて実用的なデフォルト設定がされています。手始めに、以下に最低限の永続ユニットの設定を示します。

    <persistence-unit name="sample">

       <jta-data-source

    >java:/DefaultDS</jta-data-source>

       <properties>

          [...]

          <!-- use a file system based index -->

          <property name="hibernate.search.default.directory_provider"

             value="org.hibernate.search.store.FSDirectoryProvider"/>

          <!-- directory where the indexes will be stored -->

          <property name="hibernate.search.default.indexBase"

             value="/Users/prod/apps/dvdstore/dvdindexes"/>

       </properties>

    </persistence-unit

    >

Hibernate Annotations か、EntityManager 3.2.x (JBoss AS 4.2.x 以降に組み込まれているもの)を使用する予定なら、適切なイベントリスナーの設定も行う必要があります。

    <persistence-unit name="sample">

       <jta-data-source

    >java:/DefaultDS</jta-data-source>

       <properties>

          [...]

          <!-- use a file system based index -->

          <property name="hibernate.search.default.directory_provider"

                    value="org.hibernate.search.store.FSDirectoryProvider"/>

          <!-- directory where the indexes will be stored -->

          <property name="hibernate.search.default.indexBase"

                    value="/Users/prod/apps/dvdstore/dvdindexes"/>

          <property name="hibernate.ejb.event.post-insert"

                    value="org.hibernate.search.event.FullTextIndexEventListener"/>

          <property name="hibernate.ejb.event.post-update"

                    value="org.hibernate.search.event.FullTextIndexEventListener"/>

          <property name="hibernate.ejb.event.post-delete"

                    value="org.hibernate.search.event.FullTextIndexEventListener"/>

       </properties>

    </persistence-unit

    >

## 注意

Hibernate Annotations や EntityManager 3.3.x が使われているなら、もうイベントリスナーを登録する必要はありません。 Hibernate Search 3.1.x を使っているともっとイベントリスナーが必要になりますが、Hibernate Annotations によって自動的に登録されるのです。EntityManager と Annotationsを使わないで設定する場合はHibernate Search リファレンスをご覧下さい。

この設定ファイルに加えて、以下の jar ファイルがデプロイされます:

- hibernate-search.jar

- hibernate-commons-annotations.jar

- lucene-core.jar

## 注意

これらを EAR ファイル内にデプロイする場合、`application.xml` の更新を忘れずに行ってください。

## 29.3. 使い方

Hibernate Search は、エンティティを Lucence のインデックスに割り当てるために、アノテーションを使用します。詳細については、リファレンスマニュアル を参照してください。

Hibernate Search は、API と JPA/Hibernate のセマンティックスを完全に一体化しています。HQL と検索条件ベースの問い合わせの間の切り替えは、少しのコードを追加するだけで行うことができます。アプリケーションが使用するおもな API は、`FullTextSession` API です。(Hibernate の `Session` のサブクラスです)。

Hibernate Search が発生したときに、JBoss Seam は FullTextSession を注入します。

    @Stateful

    @Name("search")

    public class FullTextSearchAction implements FullTextSearch, Serializable {

       @In FullTextSession session;

       public void search(String searchString) {

          org.apache.lucene.search.Query luceneQuery = getLuceneQuery();

          org.hibernate.Query query session.createFullTextQuery(luceneQuery, Product.class);

          searchResults = query

                .setMaxResults(pageSize + 1)

                .setFirstResult(pageSize * currentPage)

                .list();

       }

       [...]

    }

## 注意

`FullTextSession` は `org.hibernate.Session` を継承しますので、通常の Hibernate Session のように使用することが可能です。

Java Persistance API が使用された場合には、より円滑な統合が提案されます。

    @Stateful

    @Name("search")

    public class FullTextSearchAction implements FullTextSearch, Serializable {

       @In FullTextEntityManager em;

       public void search(String searchString) {

          org.apache.lucene.search.Query luceneQuery = getLuceneQuery();

          javax.persistence.Query query = em.createFullTextQuery(luceneQuery, Product.class);

          searchResults = query

                .setMaxResults(pageSize + 1)

                .setFirstResult(pageSize * currentPage)

                .getResultList();

       }

       [...]

    }

Hibernate Search が発生したときに、JBoss Seam は `FullTextEntityManager` を注入します。`FullTextEntityManager` は、検索を定義したメソッドを持つ `EntityManager` を継承します。また同様にして、`FullTextSession` は `Session` を継承します。

EJB 3.0 Session またはメッセージ駆動型Bean(Message Driven Bean) の注入が使用されたとき(たとえば、@PersistenceContext アノテーション経由で)、宣言文内で `EntityManager` インタフェースを `FullTextEntityManager` インタフェースに置き換えることはできません。しかしながら、注入される実装は `FullTextEntityManager` の実装になるでしょう。ダウンキャスト自体は可能です。

    @Stateful

    @Name("search")

    public class FullTextSearchAction implements FullTextSearch, Serializable {

       @PersistenceContext EntityManager em;

       public void search(String searchString) {

          org.apache.lucene.search.Query luceneQuery = getLuceneQuery();

          FullTextEntityManager ftEm = (FullTextEntityManager) em;

          javax.persistence.Query query = ftEm.createFullTextQuery(luceneQuery, Product.class);

          searchResults = query

                .setMaxResults(pageSize + 1)

                .setFirstResult(pageSize * currentPage)

                .getResultList();

       }

       [...]

    }

## 注意

Seam 以外で Hibernate Search に慣れている方は、`Search.createFullTextSession` を使用する必要がないことに注意してください。

DVDStore か JBoss Seam の配布物である blog サンプルプログラムで、Hibernate Search の具体的な使用例を確認してください。

- 前のページ第28章 Guice 統合
- 上に戻る
- ホーム
- 次のページ第30章 Seam の設定と Seam アプリケーションのパッケージング