SeamFramework.orgCommunity Documentation

第29章 Hibernate Search

29.1. はじめに
29.2. 設定
29.3. 使い方

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

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

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

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>

If you plan to target Hibernate Annotations or EntityManager 3.2.x (embedded into JBoss AS 4.2.x and later), you also need to configure the appropriate event listeners.


<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>

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

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();
   }
   [...]
}

注意

FullTextSessionorg.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 を継承します。また同様にして、FullTextSessionSession を継承します。

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 の具体的な使用例を確認してください。