Ok for the domain classes. Now we need to modify the JPA Test class in order to perform the actual search. In order to perform a search the common approach is to create a Lucene query and then wrap this into a Query object (JPA/Hibernate).
The Lucene query can in turn be performed either using Lucene API or Hibernate Search query DSL. In this example we will use the latter approach.

If you want to learn more about both options, see this as reference:



package com.mastertheboss.jpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.query.dsl.QueryBuilder;

import com.mastertheboss.domain.Employee;
import com.mastertheboss.domain.Department;

public class JpaTest {

    private EntityManager manager;

    public JpaTest(EntityManager manager) {
        this.manager = manager;

     * @param args
    public static void main(String[] args) {
        EntityManagerFactory factory = Persistence
        EntityManager manager = factory.createEntityManager();
        JpaTest test = new JpaTest(manager);

        EntityTransaction tx = manager.getTransaction();
        try {
        } catch (Exception e) {


        System.out.println(".. done");

    private void createEmployees() {
        int numOfEmployees = manager
                .createQuery("Select a From Employee a", Employee.class)
        if (numOfEmployees == 0) {
            Department department = new Department("java");

            manager.persist(new Employee("Jakab Gipsz", department));
            manager.persist(new Employee("Captain Nemo", department));


    private void listEmployees(EntityManager em) {

        FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search

        try {
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block


        QueryBuilder qb = fullTextEntityManager.getSearchFactory()
        org.apache.lucene.search.Query query = qb.keyword().onFields("name")

        // wrap Lucene query in a javax.persistence.Query
        javax.persistence.Query persistenceQuery = fullTextEntityManager
                .createFullTextQuery(query, Employee.class);

        // execute search
        List<Employee> result = persistenceQuery.getResultList();
        System.out.println("num of employess:" + result);
        for (Employee next : result) {
            System.out.println("next employee: " + next);



The core search functionality is contained into the listEmployees which list the Employees filtered by name: let's comment the first part of it:
        FullTextEntityManager fullTextEntityManager =

        try {
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block

This code takes care to trigger the index creation for the first time you execute the application (remember Hibernate Search will transparently index every entity persisted, updated or removed, however you have to create an initial Lucene index). For our small data set, this operation takes less than a minute. For larger data sets, it wouldn’t make sense to re-index everything every time you start the application.

Next, using the Query builder, you can then build queries. It is important to realize that the end result of a QueryBuilder is a Lucene query. For this reason you can easily mix and match queries generated via Lucene's query parser or Query objects you have assembled with the Lucene programmatic API and use them with the Hibernate Search DSL.

Running the Hibernate search example

The simplest way to run the example is using maven and adding the Hibernate search dependency:
<?xml version="1.0" encoding="UTF-8"?>
<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">


Let's run the main class as usual:
$ mvn compile exec:java -Dexec.mainClass=com.mastertheboss.jpa.JpaTest
[INFO] Scanning for projects...
. . . . .
INFO: HSEARCH000034: Hibernate Search 4.1.1.Final
12-ott-2012 10.41.32 org.hibernate.search.impl.ConfigContext getLuceneMatchVersion
WARN: HSEARCH000075: Configuration setting hibernate.search.lucene_version was not specified, using LUCENE_CURRENT.
12-ott-2012 10.41.33 org.hibernate.search.indexes.serialization.avro.impl.AvroSerializationProvider <init>
INFO: HSEARCH000079: Serialization protocol version 1.0
12-ott-2012 10.41.36 org.hibernate.search.impl.SimpleIndexingProgressMonitor addToTotalCount
INFO: HSEARCH000027: Going to reindex 2 entities
12-ott-2012 10.41.36 org.hibernate.search.impl.SimpleIndexingProgressMonitor indexingCompleted
INFO: HSEARCH000028: Reindexed 2 entities
num of employess:[Employee [id=2, name=Captain Nemo, department=java]]
next employee: Employee [id=2, name=Captain Nemo, department=java]