Hibernate Search in a JPA application

来源:互联网 发布:资产管理公司 知乎 编辑:程序博客网 时间:2024/05/16 09:16

1:I downloaded the Hibernate Search JARs and documentation from http://search.hibernate.org, and added them to my project. This PDF is an excellect source of documentation for using the Hibernate Search library with either JPA or the default Hibernate interfaces.

 

2:I added the following Search properties to the Hibernate configuration. Since I'm using JPA, I added these properties to the persistence-unit element in persistence.xml (if you're using classic Hibernate, these would get added to hibernate.properties or hibernate.cfg.xml).

 

<property name="hibernate.search.default.directory_provider"value="org.hibernate.search.store.FSDirectoryProvider" />

<property name="hibernate.search.indexing_strategy" value="manual" />

<property name="hibernate.search.default.indexBase" value="/var/searchindex" />

 

3:I added Hibernate Search annotations to my JPA entities so that the Search library can properly index and search them. Here's an example of my Song class, before and after adding the annotations

 

@Entity@Table(name="song")

public class Song implements Serializable {

private static final long serialVersionUID = 1L; // yeah, lazy, I know

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

@Column(name = "id")

private Long id;

@Column(name = "name", length = 100, nullable = false)

private String name;

@Column(name = "lyrics", length=5000, nullable = true)

private String lyrics;// other attributes and methods}

 

4:After (new annotations added at the top):

@Indexed

@Entity

@Table(name="song")

public class Song implements Serializable {

private static final long serialVersionUID = 1L; // yeah, lazy, I know

@DocumentId // the equivalent of @Id for the Hibernate Search indexes

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

@Column(name = "id")

private Long id;

@Field(index = Index.TOKENIZED, store = Store.NO)

@Boost(value = 2.0f) // boosts the importance of the song name when searching

@Column(name = "name", length = 100, nullable = false)

private String name;

@Field(index = Index.TOKENIZED, store = Store.NO)

@Column(name = "lyrics", length=5000, nullable = true)

private String lyrics;// other attributes and methods

}

 

 

@Transactional

public class SongDAO extends JpaDaoSupport implements SongService {

@SuppressWarnings("unchecked")public void updateIndexes()

{final List songs = getJpaTemplate().find("select s from Song s");getJpaTemplate().execute(new JpaCallback() {

@Overridepublic Object doInJpa(EntityManager em) throws PersistenceException {

FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);

for (Song song : songs) {

fullTextEntityManager.index(song);

}fullTextEntityManager.getSearchFactory().optimize(Song.class);return null;}});

}// other methods

}

 

@Transactional
public class SongDAO extends JpaDaoSupport implements SongService {
 @SuppressWarnings("unchecked")
 public List search(final String searchString) {
  final String[] fields = new String[]{"name", "lyrics"}; // search on these fields
  return (List) getJpaTemplate().execute(new JpaCallback() {
   @Override
   public Object doInJpa(EntityManager em) throws PersistenceException {
    List results = new ArrayList();
    try {
     FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
     MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, new StandardAnalyzer());
     parser.setDefaultOperator(QueryParser.AND_OPERATOR); // overrides the default OR_OPERATOR, so that all words in the search are required
     org.apache.lucene.search.Query query = parser.parse(searchString);
     Query fullTextQuery = fullTextEntityManager.createFullTextQuery(query, Song.class);
     results = fullTextQuery.getResultList();
    }
    catch (Exception e) {
     throw new PersistenceException(e);
    }
    return results;
   }
  });
 }
}

 

 

 

 

原创粉丝点击