Hibernate Search Annotations Example
To achieve this you have to add a few annotations to the Book and Author class. The first annotation @Indexed marks Book as indexable. By design Hibernate Search needs to store an untokenized id in the index to ensure index unicity for a given entity. @DocumentId marks the property to use for this purpose and is in most cases the same as the database primary key. The @DocumentId annotation is optional in the case where an @Id annotation exists. Next you have to mark the fields you want to make searchable. Let's start with title and subtitle and annotate both with @Field. The parameter index=Index.TOKENIZED will ensure that the text will be tokenized using the default Lucene analyzer. Usually, tokenizing means chunking a sentence into individual words and potentially excluding common words like 'a' or 'the'. We will talk more about analyzers a little later on. The second parameter we specify within @Field, store=Store.NO, ensures that the actual data will not be stored in the index. Whether this data is stored in the index or not has nothing to do with the ability to search for it. From Lucene's perspective it is not necessary to keep the data once the index is created. The benefit of storing it is the ability to retrieve it via projections ( see Section 5.1.3.5, “Projection�). Without projections, Hibernate Search will per default execute a Lucene query in order to find the database identifiers of the entities matching the query critera and use these identifiers to retrieve managed objects from the database. The decision for or against projection has to be made on a case to case basis. The default behaviour is recommended since it returns managed objects whereas projections only return object arrays. After this short look under the hood let's go back to annotating the Book class. Another annotation we have not yet discussed is @DateBridge. This annotation is one of the built-in field bridges in Hibernate Search. The Lucene index is purely string based. For this reason Hibernate Search must convert the data types of the indexed fields to strings and vice versa. A range of predefined bridges are provided, including the DateBridge which will convert a java.util.Date into a String with the specified resolution. For more details see Section 4.4, “Bridges�. This leaves us with @IndexedEmbedded. This annotation is used to index associated entities (@ManyToMany, @*ToOne and @Embedded) as part of the owning entity. This is needed since a Lucene index document is a flat data structure which does not know anything about object relations. To ensure that the authors' name will be searchable you have to make sure that the names are indexed as part of the book itself. On top of @IndexedEmbedded you will also have to mark all fields of the associated entity you want to have included in the index with @Indexed. For more details see Section 4.1.3, “Embedded and associated objects�. These settings should be sufficient for now. For more details on entity mapping refer to Section 4.1, “Mapping an entity�. Example 1.5. Example entities after adding Hibernate Search annotations package example; ... @Entity @Indexed public class Book {   @Id   @GeneratedValue   private Integer id;     @Field(index=Index.TOKENIZED, store=Store.NO)   private String title;     @Field(index=Index.TOKENIZED, store=Store.NO)   private String subtitle;   @IndexedEmbedded   @ManyToMany   private Set  authors = new HashSet(); @Field(index = Index.UN_TOKENIZED, store = Store.YES) @DateBridge(resolution = Resolution.DAY)   private Date publicationDate;     public Book() {   }     // standard getters/setters follow here   ... } package example; ... @Entity public class Author {   @Id   @GeneratedValue   private Integer id;   @Field(index=Index.TOKENIZED, store=Store.NO)   private String name;   public Author() {   }    // standard getters/setters follow here   ... }