Quantcast
Channel: Free practice test , mock test, driving test, interview questions » hibernate search
Viewing all articles
Browse latest Browse all 2

Hibernate Search – Getting Started

$
0
0

Once your dynamic site has gone bigger, data in relational database has grown, there is always a need for searching the contents. SQL queries with like ‘%…%’ are useful. But to do multiple columns / table searching, we’ll need to have big SQL queries with different conditions, ANDed and ORed. Such searching is not realistic and can not be maintained and extended easily.
For Hibernate users, Hibernate search helps searching rows from database. Without writing any complex SQL queries, you can search multiple columns and get related objects from db.

In our site Skill-Guru , you will notice a search box on the right hand side.  We have enabled the search on few tables and columns initially. Currently it will search for the tests , description and keywords for the input keyword.

Hibernate search searches objects from text queries. It uses Apache Lucene Indexing technique. It indexes the tables with the help of annotations. Also it does the synchronization of database and index. Following tutorial demonstrates a simple searching example using hibernate search. The application uses JPA way.

Consider any site selling some products. You want to search products by title, description etc. Consider following products table.

create table product(
id int(5) not null auto_increment,
title varchar(100) not null,
description varchar(250) not null,
manufacture_date datetime,
primary key(id));
To start with Hibernate Search , you must have hibernate search downloaded. Download Hibernate search 3.1.1 and Hibernate 3.
Create a java application and add required jars to your build path. Click here to know exact jars used in this project.

Crate a src/META-INF directory and create a persistence.xml file with following contents (edit it according to your database parameters)

<?xml version=”1.0″ encoding=”UTF-8″?>
<persistence 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” version=”1.0″>

<persistence-unit name=”defaultManager”
transaction-type=”RESOURCE_LOCAL”>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name=”hibernate.connection.driver_class”
value=”com.mysql.jdbc.Driver” />
<property name=”hibernate.connection.url”
value=”jdbc:mysql://localhost:3306/hibernatetest” ></property>
<property name=”hibernate.connection.username” value=”root” />
<property name=”hibernate.connection.password”
value=”root” />
<property name=”hibernate.show_sql” value=”false” />

<property name=”hibernate.search.default.directory_provider”
value=”org.hibernate.search.store.FSDirectoryProvider” />
<property name=”hibernate.search.indexing_strategy” value=”manual” />
<property name=”hibernate.search.default.indexBase” value=”e:\indexes” />
</properties>
</persistence-unit>
</persistence>

Make sure you have database url, username and password entered properly. Another important factor is the indexBase directory. Hibernate search creates indexes for each table it need to search and those indexes will be saved in this directory.

The properties:
<property name=”hibernate.search.default.directory_provider”
value=”org.hibernate.search.store.FSDirectoryProvider” />
<property name=”hibernate.search.indexing_strategy” value=”manual” />
<property name=”hibernate.search.default.indexBase” value=”e:\indexes” />
are used by Hibernate Search.

Create test.eo package and create a ProductEO class. The ProductEO entity class for products table might look like below:

Create test.eo package and create a ProductEO class. The ProductEO entity class for products table might look like below:

package test.eo;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name=”product”)
public class ProductEO {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name=”id”)
private Integer id;

@Column(name=”title”)
private String title;

@Column(name=”description”)
private String description;

@Column(name=”manufacture_date”)
private Date manifactureDate;

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 getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getManifactureDate() {
return manifactureDate;
}
public void setManifactureDate(Date manifactureDate) {
this.manifactureDate = manifactureDate;
}
}

To make this entity to be able to be searched, we need to add some more annotations. Altered Entity class is shown below:

package test.eo;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.search.annotations.DocumentId;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Store;

@Entity
@Table(name=”product”)
@Indexed
public class ProductEO {

@DocumentId
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name=”id”)
private Integer id;

@Field(index=Index.TOKENIZED, store=Store.NO)
@Column(name=”title”)
private String title;

@Field(index=Index.TOKENIZED, store=Store.NO)
@Column(name=”description”)
private String description;

@Column(name=”manufacture_date”)
private Date manifactureDate;

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 getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getManifactureDate() {
return manifactureDate;
}
public void setManifactureDate(Date manifactureDate) {
this.manifactureDate = manifactureDate;
}
}

We added following:

1. @Indexed annotation to Class
2. @DocumentId annotation on the primary key. Hibernate Search needs to store an id in the index to ensure index uniqueness for a given entity. This annotation marks that unique property. In most of the cases this will be the primary key.
3. @Field(index=Index.TOKENIZED, store=Store.NO) annotation on the fields, which need to be matched while searching. The parameter
index=Index.TOKENIZED will ensure that the text will be tokenized (in short words will be identified) using the default Lucene analyzer. store=Store.NO is to  ensures that the actual data will not be stored in the index.

Now define a HibernateEntitymanagerHelper class in package test.services to initialize persistence context as below:

package test.services;
import javax.persistence.*;
public class HibernateEntitymanagerHelper {
private static EntityManagerFactory emf;
static{
try{
emf = Persistence.createEntityManagerFactory(“defaultManager”);
}catch(Throwable tw){
throw new ExceptionInInitializerError(tw);
}
}
public static EntityManagerFactory getEntityManagerFactory() {
return emf;
}
public static void shutdown() {
emf.close();
}
}

Create following AddProducts  class in test.services package and add some data into the table:

package test.services;

import javax.persistence.EntityManager;
import test.eo.*;
import java.util.Date;

public class AddProducts {
public static void main(String[] args) {
try{
EntityManager em = HibernateEntitymanagerHelper.getEntityManagerFactory().createEntityManager();
em.getTransaction().begin();
ProductEO prodEO = new ProductEO();
prodEO.setTitle(“Mike”);
prodEO.setDescription(“XXX company Mike”);
prodEO.setManifactureDate(new Date());
em.persist(prodEO);

prodEO = new ProductEO();
prodEO.setTitle(“Phone”);
prodEO.setDescription(“YYY company Phone”);
prodEO.setManifactureDate(new Date());
em.persist(prodEO);

prodEO = new ProductEO();
prodEO.setTitle(“Microphone”);
prodEO.setDescription(“YYY company Microphone”);
prodEO.setManifactureDate(new Date());

em.persist(prodEO);
em.getTransaction().commit();

}catch(Exception e){
e.printStackTrace();
}
}
}

Now, this is time to test. For Hibernate search to work you have to trigger an initial Indexing to populate the Lucene index with the data already present in your database.  Following code creates indexes and then does searching.

package test.services;

import java.util.List;

import javax.persistence.EntityManager;
import test.eo.*;
import java.util.Date;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search;

public class ProductService {

/**
* @param args
*/
public static void main(String[] args) {

try{
EntityManager em = HibernateEntitymanagerHelper.getEntityManagerFactory().createEntityManager();
FullTextEntityManager fullTextEntityManager =  Search.getFullTextEntityManager(em);

fullTextEntityManager.getTransaction().begin();

List<ProductEO> products = em.createQuery(“select product  from ProductEO as  product”).getResultList();
for (ProductEO product : products) {
fullTextEntityManager.index(product);
System.out.println(“Product”+product.getTitle());
}

String[] fields = new String[]{“title”, “description”};
MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, new StandardAnalyzer());
// parser.setDefaultOperator(QueryParser.AND_OPERATOR);

/*
* Search only by lowercase
*/
org.apache.lucene.search.Query query = parser.parse( “phone” );
// wrap Lucene query in a javax.persistence.Query
javax.persistence.Query persistenceQuery =  fullTextEntityManager.createFullTextQuery(query, ProductEO.class);
// execute search
List<ProductEO> result = persistenceQuery.getResultList();
System.out.println(“result ::”+result);
for (ProductEO product : result) {
System.out.println(“product ::”+product.getTitle());
}

fullTextEntityManager.getTransaction().commit();
em.close();
HibernateEntitymanagerHelper.shutdown();
}catch(Exception e){
e.printStackTrace();
}

}

}

Going for an interview or want to test your hibernate skills , check out our hibernate interview questions


Viewing all articles
Browse latest Browse all 2

Trending Articles