Using Hibernate With Eclipse

scarcehoseSoftware and s/w Development

Jul 14, 2012 (4 years and 9 months ago)

344 views



Using Hibernate With Eclipse
In-Memory Database
Thomas Engelin
© Itancan Consulting AB 2008
Thomas Engelin, Itancan Consulting AB
Using Hibernate With Eclipse - In-Memory Database
1


1. Terminology

1.1. Abbreviations

ORM Object-Relational Mapping
PK Primary Key
POJO Plain Old Java Object
RCP Rich Client Platform
1.2. Definitions

Bundling Creating an Eclipse plug-in from third-party JARs
Hibernate Open source ORM framework
HSQLDB Open source relational database
Thomas Engelin, Itancan Consulting AB
Using Hibernate With Eclipse - In-Memory Database
2


2. Abstract

It is pretty common to find programmers struggling with setting up and using Hibernate to
access a database from within Eclipse RCP applications. This document is intended as a quick
guide with the basic steps on how to make this work.

The main software used is in this document is: ￿ SuSE Linux (SLES9)
￿ Eclipse SDK 3.4.1
￿ Eclipse RCP SDK 3.4
￿ Hibernate 3.3.1.GA
￿ HSQLDB 1.8.0.10
2.1. Who should read this?

Eclipse developers.
Thomas Engelin, Itancan Consulting AB
Using Hibernate With Eclipse - In-Memory Database
3


3. Problem Statement

Eclipse RCP (or plug-in) developers sometimes need to use a database for storing application-
or domain information. A common way forward is to use an ORM framework such as JDO, iBatis,
ObJectRelationalBridge or Hibernate, which is the ORM choice in this document.

An ORM framework takes care of the mapping between plain Java objects (POJOs) and the
relational database model. Once up and running, the ORM framework simplifies the parts of the
coding that has to do with persistence.
The hard part is to get things up and running! What follows is a brief step-by-step description
on how to access a database (HSQLDB) from within an Eclipse RCP application using Hibernate
as ORM framework.
Thomas Engelin, Itancan Consulting AB
Using Hibernate With Eclipse - In-Memory Database
4


4. Data Model

Just to have something concrete to work with, assume we’re developing an application that
stores questions together with correct answer(s) and hints (suggestions). The problem domain
architecture could look like this (white boxes indicate domain classes, shaded boxes indicate
infrastructure classes):

The database will store a number of Questions, where each Question has one or several correct
Answers and any (including zero) number of Suggestions. These classes will be used in the
actual application, and when we store this model as a data model we end up with only one table:



Multiple answers and suggestions will be stored as one string in the database, separated with a
delimiter character (very simple solution).
The QuestionBean class will be the glue between the Eclipse RCP application and Hibernate, but
more about that later.
QUESTIONS


ID integer <<PK>>
QUESTION varchar
ANSWERS varchar
SUGGESTIONS varchar
Suggestion
Database
Connection
Question
Answer
*

1..*

*

QuestionBean
Thomas Engelin, Itancan Consulting AB
Using Hibernate With Eclipse - In-Memory Database
5


5. Set Up HSQLDB Database

Download the HSQLDB database from http://sourceforge.net/projects/hsqldb, unzip it in a
directory of your choice, enter the ‘hsqldb’ directory and run these commands:
$ cp demo/runManager.sh data/
$ cp demo/runServer.sh data/
$ cat > data/shutdown.sh
java –cp ../lib/hsqldb.jar org.hsqldb.util.ShutdownServer
^D
$ chmod a+x data/shutdown.sh
$ cat > data/server.properties
server.database=questions
server.port=9001
^D
$ cd data
$ ./runServer.sh &
$ ./runManager.sh &
You can use the database manager after entering the following values in the shown dialog:

Setting Name: questions DB
Type: HSQL Database Engine In-Memory
Driver: org.hsqldb.jdbcDriver
URL: jdbc:hsqldb:hsql://localhost:9001
User: sa
Password: <leave blank>

To set up the database schema, create a file ‘setup.sql’ containing:
CREATE TABLE QUESTIONS
(
ID INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1),
QUESTION VARCHAR NOT NULL,
ANSWERS VARCHAR NOT NULL,
SUGGESTIONS VARCHAR NOT NULL,
PRIMARY KEY (ID)
)
In the database manager, select File > Open Script…, select your ‘setup.sql’ file and press OK,
then hit the Execute button. Select View > Refresh Tree to see the result.

The database setup is now finished. Close the database manager but leave the database server
running.
Thomas Engelin, Itancan Consulting AB
Using Hibernate With Eclipse - In-Memory Database
6


6. Set Up Eclipse For RCP Development

Before starting development, the ‘target’ needs to be set up. Download the RCP SDK (for
example eclipse-RCP-SDK-3.4-linux-gtk.tgz) and unpack it in a location separated from the
standard Eclipse installation.
To hook the development environment and target together in Eclipse, go to Window >
Preferences > Plug-in Development > Target Platform and set the location of the downloaded
target distribution. Click Reload, make sure all plug-ins are checked, and then press OK.
Thomas Engelin, Itancan Consulting AB
Using Hibernate With Eclipse - In-Memory Database
7


7. Create a Hibernate Plug-In (Bundling)

This step will bundle JAR files from a Hibernate distribution into an Eclipse plug-in that can be
used from your Eclipse RCP application.
Download the Hibernate ‘core’ from http://www.hibernate.org and unzip it in a directory of your
choice.
In Eclipse, do File > New > Project… > Plug-in Development > Plug-in from existing JAR
archives > Next > Add External. Include all JAR files from the Hibernate subdirectory
lib/required, as well as the hibernate3.jar file found directly under the Hibernate installation
directory.
Sometimes log4j issues an error message at Hibernate start up:
... java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
To avoid that, download slf4j-jdk14-1.5.2.jar (or equivalent) and add it to the project.

Finally, add hsqldb.jar from the HSQLDB distribution as well. Click Next.

Set the following values:
Project name: org.hibernate.core
Plug-in ID: org.hibernate.core
Plug-in Version: 1.0.0
Plug-in Name: Hibernate Plug-in
Plug-in Provider: Hibernate.org

Uncheck the option to unzip the JAR archives into the project. Click Finish.

To install this plug-in at the target location, it must be exported. Right-click the project and
select Export… > Plug-in Development > Deployable plug-ins and fragments > Next. Select the
new plug-in in the list of available Plug-ins.
In the Destination tab, check Directory and set its value to the target installation location (the
goal is to export the plug-in to a directory named org.hibernate.core_1.0.0 in the target’s plug-
ins directory). In the Options tab, uncheck all options. Click Finish.

Go to Window > Preferences > Plug-in Development > Target Platform, click Reload, make sure
the newly added plug-in is selected, then press OK.
Thomas Engelin, Itancan Consulting AB
Using Hibernate With Eclipse - In-Memory Database
8


8. Create Eclipse RCP Project

In this section we will create the actual RCP project, some Hibernate support code, and the Java
class that will be used in the ORM mapping. The application code itself is left out.
8.1. The Eclipse RCP project

Create a new Plug-in Project with the following settings:

Project name: com.itancan.quiz
Plug-in ID: com.itancan.quiz
Plug-in Version: 1.0.0
Plug-in Name: Quiz
Plug-in Provider: Itancan Consulting

Select the Hello RCP template, click Next and then Finish.

In the manifest editor, select the Dependencies tab and add org.hibernate.core to the list of
Required Plug-ins.
8.2. The ORM mapping Java file

Next, create the Java Bean class used in the ORM mapping, QuestionBean.java:
package com.itancan.quiz;
public class QuestionBean {
private Long id;
private String question;
private String answers;
private String suggestions;
public QuestionBean() {}
protected void setId(Long id) {
this.id = id;
}
public void setQuestion(String question) {
this.question = question;
}
public void setAnswers(String answers) {
this.answers = answers;
}
public void setSuggestions(String suggestions) {
this.suggestions = suggestions;
}
public Long getId() { return this.id; }
public String getQuestion() { return this.question; }
public String getAnswers() { return this.answers; }
public String getSuggestions() { return this.suggestions; }
}

Thomas Engelin, Itancan Consulting AB
Using Hibernate With Eclipse - In-Memory Database
9


8.3. Hibernate support code

Next, create Hibernate support code, HibernateUtil.java:
package com.itancan.quiz;
import java.io.File;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static SessionFactory sessionFactory = null;

public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
try {
sessionFactory = new Configuration().
configure(new File("hibernate.cfg.xml")).buildSessionFactory();
}
catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
return sessionFactory;
}
}
8.4. Eclipse run configuration

Next, we need to create an Eclipse Application run configuration. Enter the following values on
the Main tab:
Name: Quiz
Location: ${workspace_loc}/../runtime-com.itancan.quiz
Run an application: com.itancan.quiz.application

Enter the following values on the Arguments tab:
Program arguments: -os ${target.os} -ws ${target.ws} -arch ${target.arch} –nl
${target.nl} -consoleLog
Working directory: ${workspace_loc}/../runtime-com.itancan.quiz

In the Plug-ins tab, enter:
Launch with: plug-ins selected below only

Press Deselect All, then select com.itancan.quiz and press Add Required Plug-ins. Deselect the
org.hibernate.core plug-in from the Workspace and select it in the Target Platform instead. Save
the run configuration by pressing Apply.
It should now be possible to launch the RCP application, which of course is empty and can do
nothing.
Thomas Engelin, Itancan Consulting AB
Using Hibernate With Eclipse - In-Memory Database
10


9. Create Test Driver Code

To set up a really simple test driver, create a menu with two menu items, ‘Fill’ and ‘List’. Here’s
sample code for the ‘Fill’ action:
public void run() {
QuestionBean bean1 = new QuestionBean();
bean1.setQuestion("World's greatest platform?");
bean1.setAnswers("Eclipse");
bean1.setSuggestions("Open source | Originally by IBM");

QuestionBean bean2 = new QuestionBean();
bean2.setQuestion("Great language?");
bean2.setAnswers("Java | Eiffel");
bean2.setSuggestions("Think of an oak or a high tower");

org.hibernate.Session session =
HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
session.save(bean1);
session.save(bean2);
session.getTransaction().commit();
}
Sample code for the ‘List’ action:
public void run() {
org.hibernate.Session session =
HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
List<QuestionBean> beans =
session.createQuery("from QuestionBean").list();
for (QuestionBean bean : beans) {
System.out.println("Question: " + bean.getQuestion());
System.out.println("Answers: " + bean.getAnswers());
System.out.println("Suggestions: " + bean.getSuggestions());
}
session.getTransaction().commit();
}
If you run the RCP application and trigger one of the actions, you will get exceptions since the
file hibernate.cfg.xml does not exist. Also, we haven’t described the mapping to Hibernate yet.
We will do that next.
Thomas Engelin, Itancan Consulting AB
Using Hibernate With Eclipse - In-Memory Database
11


10. Create the Hibernate Configuration File

This file describes database properties and points to mapping files. Create the following file in
the runtime location (see the run configuration) and name it hibernate.cfg.xml:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">
org.hsqldb.jdbcDriver
</property>
<property name="connection.url">
jdbc:hsqldb:hsql://localhost:9001
</property>
<property name="connection.username">sa</property>
<property name="connection.password"></property>

<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>

<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>

<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>

<!-- Disable the second-level cache -->
<property name="cache.provider_class">
org.hibernate.cache.NoCacheProvider
</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping file="QuestionBean.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Running the application again, another exception says that the file QuestionBean.hbm.xml is
missing. We deal with that next.
Thomas Engelin, Itancan Consulting AB
Using Hibernate With Eclipse - In-Memory Database
12


11. Create the Hibernate Mapping File

This file describes database mapping. Create the following file in the runtime location (see the
run configuration) and name it QuestionBean.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.itancan.quiz.QuestionBean" table="QUESTIONS">
<id name="id" column="ID">
<generator class="native"/>
</id>
<property name="question" column="QUESTION"/>
<property name="answers" column="ANSWERS"/>
<property name="suggestions" column="SUGGESTIONS"/>
</class>
</hibernate-mapping>
Running the application, an exception says that the class QuestionBean can not be found. This
has to do with Eclipse class loading and third-party libraries.

The problem is that the org.hibernate.core plug-in depends on the the RCP application’s class
QuestionBean, and this class does not have the correct visibility.

A mechanism called ‘Buddy classloading’ offers an integration strategy that does not require
code modification, and that can be used in situations like this.

In the MANIFEST.MF file for the org.hibernate.core plug-in, add the following line and re-export
the plug-in to the target platform:
...
Eclipse-BuddyPolicy: registered
...
In the MANIFEST.MF file for the RCP application, add the following line:
...
Eclipse-RegisterBuddy: org.hibernate.core
...
Now everything should be set up and working!!
Thomas Engelin, Itancan Consulting AB
Using Hibernate With Eclipse - In-Memory Database
13


12. Final Words

This is a very simple example, just focusing on the integration of Hibernate and an Eclipse RCP
application. For example, the packaging of the RCP application is not discussed at all.

Some of the Java code, the run configuration, the database setup, and the Hibernate
configuration files will look different in a real-world application.
Thomas Engelin, Itancan Consulting AB
Using Hibernate With Eclipse - In-Memory Database
14


13. References

http://www.hibernate.org/hib_docs/reference/en-US/html/tutorial.html

Eclipse Rich Client Platform (McAffer, Lemieux) ISBN 0-321-33461-2

Eclipse Building Commercial-Quality Plug-ins (Clayberg, Rubel) ISBN 0-321-42672-X

Agile Java Development with Spring, Hibernate and Eclipse (Hemrajani) ISBN 0-672-32896-8