The programmatic mapping API

In the beginning of this chapter we said that even when you map entities to the database with hbm.xml files, you can still use Hibernate Search annotations mapping to Lucene. However, if you really want to avoid putting annotations in your entity classes altogether, there is an API available for declaring your Lucene mappings programmatically at runtime.

This might come in handy if your search configuration needs to change at runtime based on some circumstances. It is also the only approach available if you cannot alter your entity classes for some reason, or if you are a hard-line believer in separating your configuration from your POJO's.

The heart of the programmatic mapping API is the SearchMapping class, which stores the Hibernate Search configuration that is normally pulled from annotations. Typical usage looks like the query DSL code that we saw in the previous chapter. You call a method on a SearchMapping object, call a method on the object returned, and so on in a long nested series.

The methods available at each step of the way intuitively resemble the search annotations that you have already seen. The entity() method replaces the @Entity annotation, indexed() replaces @Indexed, field() replaces @Field, and so on.

Tip

If you need to use the programmatic mapping API in an application, then you can find more details in Reference Manual and Javadocs, both available at http://www.hibernate.org/subprojects/search/docs.

The starting point in Javadocs is the org.hibernate.search.cfg.SearchMapping class, and the other relevant classes are all in the org.hibernate.search.cfg package as well.

In the downloadable source code available from the Packt Publishing website, the chapter2-mapping subdirectory contains a version of the VAPORware Marketplace application that uses the programmatic mapping API.

This version of the example application includes a factory class, with a method that configures and returns a SearchMapping object upon demand. It doesn't matter what you name the class or the method, so long as the method is annotated with @org.hibernate.search.annotations.Factory:

public class SearchMappingFactory {

   @Factory
   public SearchMapping getSearchMapping() {

      SearchMapping searchMapping = new SearchMapping();

      searchMapping
         .entity(App.class)
            .indexed()
            .interceptor(IndexWhenActiveInterceptor.class)
            .property("id", ElementType.METHOD).documentId()
            .property("name", ElementType.METHOD).field()
            .property("description", ElementType.METHOD).field()
            .property("supportedDevices",
               ElementType.METHOD).indexEmbedded().depth(1)
            .property("customerReviews",
               ElementType.METHOD).indexEmbedded().depth(1)

         .entity(Device.class)
            .property("manufacturer", ElementType.METHOD).field()
            .property("name", ElementType.METHOD).field()
            .property("supportedApps",   
               ElementType.METHOD).containedIn()
         .entity(CustomerReview.class)
            .property("stars", ElementType.METHOD).field()
            .property("comments", ElementType.METHOD).field();

      return searchMapping;
   }

}

Notice that this factory method is only three lines long, strictly speaking. The bulk of it is one continuous line of chained method calls, originating from the SearchMapping object, that map our three persistent classes.

To integrate the mapping factory into Hibernate Search, we add a property to the main hibernate.cfg.xml configuration file:

...
<property name="hibernate.search.model_mapping">
   com.packtpub.hibernatesearch.util.SearchMappingFactory
</property>
...

Now, whenever Hibernate ORM opens a Session, Hibernate Search and all of the Lucene mappings come along for the ride!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset