To explore the capabilities of Hibernate Search, we will work with a twist on the classic "Java Pet Store" sample application. Our version, the "VAPORware Marketplace", will be an online catalog of software apps. Think of such stores run by Apple, Google, Microsoft, Facebook, and… well, pretty much every other company now.
Our app market will give us plenty of opportunities to search data in different ways. Of course, there are titles and descriptions as in most product catalogs. However, software apps involve an expanded set of data points, such as genre, version, and supported devices. These different facets will let us take a look at the many features that Hibernate Search makes available.
At a high level, incorporating Hibernate Search in an application requires the following three steps:
In future projects, after we have a decent understanding of the basics, we would probably start with this third bullet-point. However, for the time being, let us jump straight into some code!
To keep things simple, this first cut of our application
will include only one entity class. This
App
class describes a software application and is the central entity with which all the other entity classes will be associated. For now though, we will give an "app" three basic data points:
package com.packtpub.hibernatesearch.domain; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class App { @Id @GeneratedValue private Long id; @Column private String name; @Column(length=1000) private String description; @Column private String image; public App() {} public App(String name, String image, String description) { this.name = name; this.image = image; this.description = description; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getImage() { return image; } public void setImage(String image) { this.image = image; } }
This class is a basic plain old Java object (POJO), just member variables and getter/setter methods for working with them. However, notice the annotations that are highlighted.
If you are accustomed to Hibernate 3.x, note that version 4.x deprecates many of Hibernate's own mapping annotations in favor of their Java Persistence API (JPA) 2.0 counterparts. We will discuss
JPA further in Chapter 3, Performing Queries. For now, simply notice that the JPA annotations here are essentially identical to their native Hibernate counterparts, other than belonging to the javax.persistence
package.
The class itself is annotated with @Entity
, which tells Hibernate
to map the class to a database table. Since we did not explicitly specify a table name, by default Hibernate will create a table named APP
for the App
class.
The id
field is annotated with both @Id
and
@GeneratedValue
. The former simply tells Hibernate that this field maps to the primary key of the database table. The latter declares that the values should be generated automatically when new rows are inserted. This is why our constructor method doesn't populate a value for id
, because we're counting on Hibernate to handle it for us.
Finally, we annotate our three data points with @Column
, telling Hibernate that these variables correspond with columns in the database table. Normally, the name of the column will be the same as the variable name, and Hibernate will assume some sensible defaults about the column length, whether to allow null
values, and so on. However, these settings may be declared explicitly (as we are doing here), by setting the column length for description to 1,000 characters.