Full Text Hibernate Lucene Search Hello World Example Using Maven and SQLite
Hibernate Search is a full text search engine built using Apache Lucene framework. Hibernate Search indexes your domain model, keep the index upto date and also performs full text search functionality to fetch matching domain objects. This Hello World example shows how you can setup hibernate search and get your domain objects based on free text search query. In this tutorial we will use Maven tool to build the project, Eclipse IDE to code and SQLite database to save our domain objects.
To make the learning easier, I have used SQLite database which is a self-contained, serverless, zero-configuration, transactional SQL database engine. But you are free to choose any other database as well to learn this tutorial. To run example shown in this tutorial, you do not have to install any database or SQLite database seperately. However to browse the database you can use 'SQLite Manager - Firefox addon' which provides a very nice GUI for SQLite database.
Tools and Technologies used in this article :
-
Hibernate Search 4.1
-
Maven
-
SQLite 3 database
-
SQLite Manager - Firefox addon
-
Eclipse 3.7
1. Create a Java Project using Maven Tool
In the command prompt execute the following command to generate Maven compatible Java project named as 'HibernateSearchHelloWorld'.
1
|
mvn archetype:generate -DgroupId=com.srccodes.example.hibernate -DartifactId=HibernateSearchHelloWorld -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode= false
|
2. Update pom.xml
Add dependency of Hibernate core and SQLite jdbc library. Also update 'maven-compiler-plugin' so that it uses compilation level 1.5 onwards. Otherwise annotation (introduced in JDK 5) will not work.
File : pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
< project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
< modelVersion >4.0.0</ modelVersion >
< groupId >com.srccodes.example.hibernate</ groupId >
< artifactId >HibernateSearchHelloWorld</ artifactId >
< packaging >jar</ packaging >
< version >1.0-SNAPSHOT</ version >
< name >HibernateSearchHelloWorld</ name >
< dependencies >
<!-- hibernate -->
< dependency >
< groupId >org.hibernate</ groupId >
< artifactId >hibernate-core</ artifactId >
< version >4.1.4.Final</ version >
</ dependency >
< dependency >
< groupId >org.hibernate</ groupId >
< artifactId >hibernate-search</ artifactId >
< version >4.1.1.Final</ version >
</ dependency >
<!-- SQLite JDBC library -->
< dependency >
< groupId >org.xerial</ groupId >
< artifactId >sqlite-jdbc</ artifactId >
< version >3.7.2</ version >
</ dependency >
<!-- junit test -->
< dependency >
< groupId >junit</ groupId >
< artifactId >junit</ artifactId >
< version >3.8.1</ version >
< scope >test</ scope >
</ dependency >
</ dependencies >
< build >
< plugins >
< plugin >
< groupId >org.apache.maven.plugins</ groupId >
< artifactId >maven-compiler-plugin</ artifactId >
< configuration >
< source >1.5</ source >
< target >1.5</ target >
</ configuration >
</ plugin >
</ plugins >
</ build >
</ project >
|
3. Convert to Eclipse compatible Java project
Open the directory 'HibernateSearchHelloWorld' in command prompt and run the following maven command.
1
|
mvn eclipse:eclipse |
On completion of the above command, Maven Java project will be converted to a Eclipse compatible java project.
Eclipse compatible Java Project structure
4. Import project in Eclipse
Open Eclipse IDE and select from the menu File --> Import --> General --> Existing Projects into Workspace
Browse to the directory of the newly converted Eclipse compatible Java Project and click 'Finish' button.
Screenshot of Eclipse project structure
5. Add Hibernate Configuration file
Right click on 'main' and select from context menu 'New' --> 'Folder'.
Enter 'resources' in the 'Folder name' field and click the 'Finish' button.
Copy the 'hibernate.cfg.xml' file in the 'resources' folder.
File: hibernate.cfg.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<? xml version = "1.0" encoding = "UTF-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" < hibernate-configuration >
< session-factory >
< property name = "show_sql" >false</ property >
< property name = "format_sql" >true</ property >
< property name = "dialect" >org.hibernate.dialect.SQLiteDialect</ property >
< property name = "connection.driver_class" >org.sqlite.JDBC</ property >
< property name = "connection.url" >jdbc:sqlite:mydb.db</ property >
< property name = "connection.username" ></ property >
< property name = "connection.password" ></ property >
< property name = "hibernate.hbm2ddl.auto" >update</ property >
< property name = "hibernate.search.default.directory_provider" >filesystem</ property >
< property name = "hibernate.search.default.indexBase" >C:\lucene\indexes</ property >
< mapping class = "com.srccodes.example.hibernate.Contact" />
</ session-factory >
</ hibernate-configuration >
|
'mydb.db' is the SQLite database file included with the sourcecode attached in 'Download Source Code' section. You can create db file of your own using 'SQLite Manager - Firefox addon' UI. But copy that file inside 'HibernateSearchHelloWorld' project directory directly.
I have set the property 'hibernate.hbm2ddl.auto' to 'update' so that when you will execute the code it will create the database tables of it's own based on the entity class 'com.srccodes.example.hibernate.Contact') we have written and referenced in this configuration file.
Set property 'hibernate.search.default.indexBase' to a writeable directory where Lucene will create index for your domain objects.
6. Configure Java Build Path
Right click on 'HibernateSearchHelloWorld' project and select from context menu 'Properties' --> 'Java Build Path'.
Add 'resources' folder as shown in the screenshot below
7. Add SQLiteDialect
Copy from attached source code or download SQLiteDialect and add under package 'org.hibernate.dialect' in your project.
dialect is used to help hibernate framework to create underlying database specific SQL query.
8. Write Entity class
Create a class 'Contact' under the package 'com.srccodes.example.hibernate' and copy the following content.
File: Contact.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
package com.srccodes.example.hibernate;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Store;
/** * The persistent class for the contact database table.
*
*/
@Entity @Indexed @Table (name = "contact" )
public class Contact {
private Integer id;
private String name;
private String email;
public Contact() {
}
public Contact(Integer id, String name, String email) {
this .id = id;
this .name = name;
this .email = email;
}
@Id
public Integer getId() {
return this .id;
}
public void setId(Integer id) {
this .id = id;
}
@Field (index = Index.YES, analyze = Analyze.YES, store = Store.NO)
public String getName() {
return this .name;
}
public void setName(String name) {
this .name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this .email = email;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder( "Id: " ).append( this .getId()).append( " | Name:" ).append( this .getName()).append( " | Email:" ).append( this .getEmail());
return stringBuilder.toString();
}
} |
To know basic hibernate annotation follow the tutorial Hibernate Hello World example using Maven build tool and SQLite database
@Indexed annotation specifies an entity as indexable.
@Field annotation specifies an field as searchable. Here Index.YES means 'name' field will indexed, Analyze.YES means that filed will be analyzed (excludes common stop words like 'a', 'an', 'and', 'the' etc) using default Lucene Analyzer, Store.NO means actual 'name' field data will not be stored in the index.
I have also written 'toString()' method which we'll use to print out domain objects in console.
9. Common utility class for Hibernate
Copy the following code to 'HibernateUtil' class of package 'com.srccodes.example.hibernate'.
File: HibernateUtil.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
package com.srccodes.example.hibernate;
import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
/** * Contains utility methods
*
* @author srccodes.com
* @version 1.0
*
*/
public class HibernateUtil {
private static SessionFactory sessionFactory = null ;
private static ServiceRegistry serviceRegistry = null ;
private static SessionFactory configureSessionFactory() throws HibernateException {
Configuration configuration = new Configuration();
configuration.configure();
Properties properties = configuration.getProperties();
serviceRegistry = new ServiceRegistryBuilder().applySettings(properties).buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
return sessionFactory;
}
// We need to configure session factory once.
// Rest of the time we will get session using the same.
static {
configureSessionFactory();
}
private HibernateUtil() {}
public static Session getSession() {
return sessionFactory.openSession();
}
} |
'configureSessionFactory()' method will build the hibernate session factory based on the configuration in 'hibernet.cfg.xml' file.
'getSession()' method will provide a Hibernate session from the configured session factory.
10. Hibernate Search and Indexing code
Copy the following code to 'App' class of package 'com.srccodes.example.hibernate'.
File: App.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
package com.srccodes.example.hibernate;
import java.util.List;
import java.util.Scanner;
import org.hibernate.Session;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.search.query.dsl.QueryBuilder;
/** * Hello world!
*
*/
public class App {
private static void doIndex() throws InterruptedException {
Session session = HibernateUtil.getSession();
FullTextSession fullTextSession = Search.getFullTextSession(session);
fullTextSession.createIndexer().startAndWait();
fullTextSession.close();
}
private static List<Contact> search(String queryString) {
Session session = HibernateUtil.getSession();
FullTextSession fullTextSession = Search.getFullTextSession(session);
QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Contact. class ).get();
org.apache.lucene.search.Query luceneQuery = queryBuilder.keyword().onFields( "name" ).matching(queryString).createQuery();
// wrap Lucene query in a javax.persistence.Query
org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery, Contact. class );
List<Contact> contactList = fullTextQuery.list();
fullTextSession.close();
return contactList;
}
private static void displayContactTableData() {
Session session = null ;
try {
session = HibernateUtil.getSession();
// Fetching saved data
List<Contact> contactList = session.createQuery( "from Contact" ).list();
for (Contact contact : contactList) {
System.out.println(contact);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (session != null ) {
session.close();
}
}
}
public static void main(String[] args) throws InterruptedException {
System.out.println( "\n\n******Data stored in Contact table******\n" );
displayContactTableData();
// Create an initial Lucene index for the data already present in the database
doIndex();
Scanner scanner = new Scanner(System.in);
String consoleInput = null ;
while ( true ) {
// Prompt the user to enter query string
System.out.print( "\n\nEnter search key (To exit type 'X')" );
consoleInput = scanner.nextLine();
if ( "X" .equalsIgnoreCase(consoleInput)) {
System.out.println( "End" );
System.exit( 0 );
}
List<Contact> result = search(consoleInput);
System.out.println( "\n\n>>>>>>Record found for '" + consoleInput + "'" );
for (Contact contact : result) {
System.out.println(contact);
}
}
}
} |
'doIndex()' method will generate indexes for your domain objects in the directory specified in the 'hibernate.search.default.indexBase' property in 'hibernate.cfg.xml' file.
'search(String queryString)' method will prepare a Lucene search query based on the query string. Then that query will be wrapped in a javax.persistence.Query which will be executed to return matching domain objects.
11. Final project structure
After doing all the changes the overall project structure will look like this
12. Populate 'Contact' table with data
Browse the 'mydb.db' SQLite database file (under 'HibernateSearchHelloWorld' project) using 'SQLite Manager - Firefox addon'. Populate the 'Contact' table with some dummy test data.
Screenshot of the table using 'SQLite Manager - Firefox addon' UI
13. Run Your Code
Right click on 'App.java' and select from context menu 'Run As' --> 'Java Application'.
13. Console Output
In the console, all the records of the 'Contact' table will be printed first. Then you will be prompted to enter search key. Based on the search key Hibernate Search API will return all the matching domain objects which will be printed in the console. To exit from the command prompt you have to type 'X'.
Console
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
Id: 1 | Name:Abhijit Ghosh | Email:abhijit@email.com Id: 3 | Name:My Name | Email:my_email@email.com Id: 5 | Name:Li Chao | Email:lichao@email.com Id: 6 | Name:Tom Li | Email:tomli@email.com Id: 24 | Name:Your Name | Email:your_email@email.com Jul 26, 2012 5:41:32 PM org.hibernate.search.impl.SimpleIndexingProgressMonitor addToTotalCount INFO: HSEARCH000027: Going to reindex 5 entities Jul 26, 2012 5:41:32 PM org.hibernate.search.impl.SimpleIndexingProgressMonitor indexingCompleted INFO: HSEARCH000028: Reindexed 5 entities Enter search key (To exit type 'X' )name
>>>>>>Record found for 'name'
Id: 3 | Name:My Name | Email:my_email@email.com Id: 24 | Name:Your Name | Email:your_email@email.com Enter search key (To exit type 'X' )Li
>>>>>>Record found for 'Li'
Id: 5 | Name:Li Chao | Email:lichao@email.com Id: 6 | Name:Tom Li | Email:tomli@email.com Enter search key (To exit type 'X' ) test
>>>>>>Record found for 'test'
Enter search key (To exit type 'X' )x
End |
Download Source Code
相关推荐
Hibernate Search is a library providing full-text search capabilities to Hibernate. It opens doors to more human friendly and efficient search engines while still following the Hibernate and Java ...
hibernate search全文索引的创建与查询实例 hibernate-search-analyzers-4.1.1.Final.jar
使用hibernate search实现全文检索和文档管理功能: 1 全文检索 2 手动生成索引 3 文档上传(自动建立索引) 4 文档更新(自动建立索引) 5 文档删除 使用说明: 1 需要先恢复数据库 searchDB_2008sqlserver.bak 2 ...
hibernate Search in action
hibernate-search, Hibernate Search Hibernate 搜索版本:5.8.0. Final - 13-09-2017描述针对Java对象的全文搜索这个项目提供 Hibernate ORM和全文索引服务( 如 Apache Lucene和 Elasticsearch
Hibernate Search 4.4.0.Final API 帮助文档
hibernate search 里面有关于代码的详细说明 请看readme txt 有相关jar直接运行
基于Spring的Hibernate Search全文检索功能示例 实例下载
HibernateSearch的使用方法
Hibernate Search的作用是对数据库中的数据进行检索的。它是hibernate对著名的全文检索系统Lucene的一个集成方案,作用在于对数据表中某些内容庞大的字段(如声明为text的字段)建立全文索引,这样通过hibernate ...
压缩包包括项目完整代码,详细说明和项目结构图,效果图 项目实现了分页和高亮显示 MAVEN项目:HibernateSearchDemo IDE :MyEclipse jdk :1.6 数据库 :MySql ...hibernate search 版本 4.4.1.Final
Hibernate Search in action (pdf && code)
Hibernate Search in Action introduces both the principles of enterprise search and the implementation details a Java developer will need to use Hibernate Search effectively. This book blends the ...
不久前Hibernate推出了Hibernate Search 3.0 GA,由它的名字大家也可以大概猜到它的作用是对数据库中的数据进行检索的。它是hibernate对著名的全文检索系统Lucene的一个集成方案,作用在于对数据表中某些内容庞大的...
NULL 博文链接:https://dreamzhong.iteye.com/blog/1213882
hibernate search reference card
Getting Started with Hibernate Search