Hibernate Search Example
Hibernate Search combines Hibernate with Lucene to enable lucene-search while making use of
Hibernate APIs.
Following is a working example made using the following files:
./pom.xml
./src/main/resources/META-INF/persistence.xml
./src/main/java/com/prismoskills/hibernate/search/HibernateSearchExample.java
./src/main/java/com/prismoskills/hibernate/search/pojos/Author.java
./src/main/java/com/prismoskills/hibernate/search/pojos/Book.java
(Assuming maven and java are already installed in the system)
pom.xml needs to have the following dependencies:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.prismoskills.hibernate.search</groupId>
<artifactId>hibernate_search_example</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>example</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3.0</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search</artifactId>
<version>4.5.0.Alpha1</version>
</dependency>
<!-- For using JPA (2) -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.0.Beta5</version>
</dependency>
<!-- Additional Analyzers -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-analyzers</artifactId>
<version>4.5.0.Alpha1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<configuration>
<transformers>
<transformer implementation=
"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.prismoskills.hibernate.search.HibernateSearchExample</Main-Class>
</manifestEntries>
</transformer>
</transformers>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
persistence.xml holds the database connectivity information.
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="DAL.pool.load" value="true" />
<property name="DAL.pool.activate" value="true" />
<property name="hibernate.search.default.directory_provider" value="filesystem"/>
<property name="hibernate.search.default.indexBase" value="./lucene/indexes"/>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.driver.OracleDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:11521:XE"/>
<property name="javax.persistence.jdbc.user" value="system"/>
<property name="javax.persistence.jdbc.password" value="manager"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
Book.java is a normal POJO.
Note the annotation @Field . It has following options:
Index ed: If a field is indexed, then its hash is computed by Lucene and it can be used as a search parameter.
Store d: If a field is stored, then the field itself is stored as such and it can be used as a selectable field.
Analyze d: Determines whether given field should be analyzed or not.
package com.prismoskills.hibernate.search.pojos;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.DateBridge;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.IndexedEmbedded;
import org.hibernate.search.annotations.Resolution;
import org.hibernate.search.annotations.Store;
@Entity
@Indexed
public class Book
{
@Id
@GeneratedValue
private Integer id;
@Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
private String title;
@Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
private String subtitle;
@Field(index = Index.YES, analyze=Analyze.NO, store = Store.YES)
@DateBridge(resolution = Resolution.DAY)
private Date publicationDate;
@IndexedEmbedded
@OneToOne
private Author author;
public Book() {}
// getter/setters
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSubtitle() {
return subtitle;
}
public void setSubtitle(String subtitle) {
this.subtitle = subtitle;
}
public Date getPublicationDate() {
return publicationDate;
}
public void setPublicationDate(Date publicationDate) {
this.publicationDate = publicationDate;
}
public Author getAuthor() {
return author;
}
public void setAuthor(Author author) {
this.author = author;
}
}
Author.java is also a POJO.
package com.prismoskills.hibernate.search.pojos;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.search.annotations.Field;
@Entity
public class Author
{
@Id
@GeneratedValue
private Integer id;
@Field
private String name;
public Author() {}
// getter/setters
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
HibernateSearchExample.java has the main() function and executes SolrDao functions.
package com.prismoskills.hibernate.search;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import org.apache.lucene.search.Query;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.hibernate.search.jpa.Search;
import org.hibernate.search.query.dsl.QueryBuilder;
import com.prismoskills.hibernate.search.pojos.Author;
import com.prismoskills.hibernate.search.pojos.Book;
public class HibernateSearchExample
{
static final String persistenceUnit = "persistenceUnit";
public static void main( String[] args )
{
System.out.println( "Hello World!" );
EntityManagerFactory factory = Persistence.createEntityManagerFactory(persistenceUnit);
System.out.println( "Created factory for " + persistenceUnit + " from persistence.xml");
EntityManager manager = factory.createEntityManager();
System.out.println( "Created entity manager from the factory" );
Author auth = new Author ();
auth.setId(1);
auth.setName("Auth Name");
Book book = new Book ();
book.setAuthor(null);
book.setId(1);
book.setPublicationDate(new Date());
book.setTitle("Title");
book.setSubtitle("Subtitle");
EntityTransaction tx = manager.getTransaction();
tx.begin();
manager.merge (book);
tx.commit();
System.out.println ("Persisted entity to the DB");
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(manager);
try
{
fullTextEntityManager.createIndexer().startAndWait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
manager.getTransaction().begin();
QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(Book.class).get();
Query query = qb.keyword().onFields("title").matching("Title").createQuery();
FullTextQuery persistenceQuery = fullTextEntityManager.createFullTextQuery(query, Book.class);
List<?> results = persistenceQuery.getResultList();
System.out.println (results.iterator().next());
manager.getTransaction().commit();
manager.close();
}
}
Results
The above can be run as:
mvn clean package
java -jar target/hibernate*.jar
Hello World!
org.hibernate.ejb.HibernatePersistence <init>
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence];
use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [
name: persistenceUnit
...]
org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.0.Beta5}
org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)
org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [oracle.jdbc.driver.OracleDriver] at URL [jdbc:oracle:thin:@localhost:11521:XE]
org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=system, password=****}
org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.Oracle10gDialect
org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
org.hibernate.search.Version <clinit>
INFO: HSEARCH000034: Hibernate Search 4.5.0.Alpha1
org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000228: Running hbm2ddl schema update
org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000102: Fetching database metadata
org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000396: Updating schema
org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000261: Table found: SYSTEM.AUTHOR
org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000037: Columns: [id, name]
org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000108: Foreign keys: []
org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000126: Indexes: [sys_c007219]
org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000261: Table found: SYSTEM.BOOK
org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000037: Columns: [id, title, subtitle, author_id, publicationdate]
org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000108: Foreign keys: [fk_author_id]
org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: HHH000126: Indexes: [sys_c007221]
org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000232: Schema update complete
org.hibernate.search.impl.ConfigContext getLuceneMatchVersion
WARN: HSEARCH000075: Configuration setting hibernate.search.lucene_version was not specified, using LUCENE_CURRENT.
Created factory for persistenceUnit from persistence.xml
Created entity manager from the factory
Hibernate:
select
book0_.id as id1_1_0_,
book0_.author_id as author_id5_1_0_,
book0_.publicationDate as publicationDate2_1_0_,
book0_.subtitle as subtitle3_1_0_,
book0_.title as title4_1_0_
from
Book book0_
where
book0_.id=?
Hibernate:
select
hibernate_sequence.nextval
from
dual
Hibernate:
insert
into
Book
(author_id, publicationDate, subtitle, title, id)
values
(?, ?, ?, ?, ?)
Persisted entity to the DB
Hibernate:
select
count(*) as y0_
from
Book this_
org.hibernate.search.impl.SimpleIndexingProgressMonitor addToTotalCount
INFO: HSEARCH000027: Going to reindex 5 entities
Hibernate:
select
this_.id as y0_
from
Book this_
org.hibernate.loader.criteria.CriteriaLoader applyLocks
WARN: HHH000444: Encountered request for locking however dialect reports that
database prefers locking be done in a separate select (follow-on locking); results will
be locked after initial query executes
Hibernate:
select
this_.id as id1_1_1_,
this_.author_id as author_id5_1_1_,
this_.publicationDate as publicationDate2_1_1_,
this_.subtitle as subtitle3_1_1_,
this_.title as title4_1_1_,
author2_.id as id1_0_0_,
author2_.name as name2_0_0_
from
Book this_
left outer join
Author author2_
on this_.author_id=author2_.id
where
this_.id in (
?, ?, ?, ?, ?
)
org.hibernate.search.impl.SimpleIndexingProgressMonitor indexingCompleted
INFO: HSEARCH000028: Reindexed 5 entities
Hibernate:
select
this_.id as id1_1_1_,
this_.author_id as author_id5_1_1_,
this_.publicationDate as publicationDate2_1_1_,
this_.subtitle as subtitle3_1_1_,
this_.title as title4_1_1_,
author2_.id as id1_0_0_,
author2_.name as name2_0_0_
from
Book this_
left outer join
Author author2_
on this_.author_id=author2_.id
where
(
this_.id in (
?, ?, ?, ?, ?
)
)