Hibernate
This article is out of date, please refer to http://books.zkoss.org/wiki/ZK_Developer%27s_Reference/Integration/Persistence_Layer/Hibernate for more up to date information.
Overview
Hibernate is an object-relational mapping (ORM) solution for the Java language. The main feature of Hibernate is that it simplifies the job of accessing a relational database.
Example here we use with Hibernate 3.3 and hsqldb 1.8. It should work with the Hibernate versions 3.6 or before. Since Hibernate 3.6 version please use Hibernate standard methods to manage Hibernate session.
Installing Hibernate
Before using Hibernate, you have to install it into your application first.
- Download hibernate core and hibernate annotations from Hibernate
- Put *.jar files from hibernate core and hibernate annotations into your $myApp/WEB-INF/lib/
$myApp represents the name of your web application. ex. event
Configuring the ZK Configuration File
To make ZK work with Hibernate smoothly, you can use the following utilities. These two utilities help applying the open session In view design pattern for you. They will open and close the hibernate session in each HTTP request automatically. If you don't want to use them, you will have to manage the Hibernate session yourself.
- Create
zk.xml
under$myApp/WEB-INF/
(if not exists) - Copy the following lines into your
zk.xml
<!-- Hibernate SessionFactory life cycle -->
<listener>
<description>Hibernate SessionFactory life cycle</description>
<listener-class>org.zkoss.zkplus.hibernate.HibernateSessionFactoryListener</listener-class>
</listener>
<!-- Hibernate OpenSessionInView life cycle -->
<listener>
<description>Hibernate Open Session In View life cycle</description>
<listener-class>org.zkoss.zkplus.hibernate.OpenSessionInViewListener</listener-class>
</listener>
$myApp
represents the name of your web application. ex. event
Creating the Java Objects
You have to create simple JavaBean class with some properties.
- Create your first Java class (
Event.java
)
package events;
import java.util.Date;
public class Event {
private Long id;
private String title;
private Date date;
public Event() {}
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
- You have to compile the Java source, and place the class file in a directory called
classes
in the Web development folder, and in its correct package. (ex.$myApp/WEB-INF/classes/event/Event.class
)
The next step is to tell Hibernate how to map this persistent class with database.
Mapping the Java Objects
There are two ways to tell Hibernate how to load and store objects of the persistent class, one is using Java Annotation, and the other older way is using Hibernate mapping file.
Using Java Annotation
The benefit of using Java annotation instead of Hibernate mapping file is that no additional file is required. Simply add Java annotation on your Java class to tell Hibernate about the mappings.
package events;
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;
@Entity
@Table(name="EVENTS")
public class Event {
private Long id;
private String title;
private Date date;
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)
@Column(name = "EVENT_ID")
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
@Column(name = "EVENT_DATE")
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
- @Entity declares this class as a persistence object
- @Table(name = "EVENTS") annotation tells that the entity is mapped with the table EVENTS in the database
- @Column element is used to map the entities with the column in the database.
- @Id element defines the mapping from that property to the primary key column.
Using the Mapping Files
- Simply create
Event.hbm.xml
for the persistent classEvent.java
.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"[http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd]">
<hibernate-mapping>
<class name="events.Event" table="EVENTS">
<id name="id" column="EVENT_ID">
<generator class="native"/>
</id>
<property name="date" type="timestamp" column="EVENT_DATE"/>
<property name="title"/>
</class>
</hibernate-mapping>
- Place this
Event.hbm.xml
in the directory calledsrc
in the development folder, and its correct package. (ex.$myApp/WEB-INF/src/event/Event.hbm.xml
)
Creating the Hibernate Configuration File
The next step is to setup Hibernate to use a database. HSQL DB, a java-based SQL DBMS, can be downloaded from the HSQL DB website(http://hsqldb.org/).
- Unzip it to a directory, say c:/hsqldb. (note: For hsqldb, the directory must be at the same partition of your web application, and under root directory)
- Copy hsqldb.jar to
$myApp/WEB-INF/lib
- Open a command box and change to c:/hsqldb/lib
- In the command prompt, execute
java -cp ../lib/hsqldb.jar org.hsqldb.Server -database.0 mydb -dbname.0 EVENTS
After installing the database, we have to setup Hibernate Configuration file. Create hibernate.cfg.xml
in the directory called src
in the development folder(ex.$myApp/WEB-INF/src/hibernate.cfg.xml
). Copy the following lines into your hibernate.cfg.xml
. It depends on how you map your Java objects. (Note: if you're using eclipse, hibernate.cfg.xml should be placed under src folder of Java Resources)
Using Java Annotation
<?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</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>
<!-- 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>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<mapping class="events.Event" />
</session-factory>
</hibernate-configuration>
Using the Mapping Files
<?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</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>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">create</property>
<mapping resource="events/Event.hbm.xml"/>
</session-factory>
</hibernate-configuration>
We continue with how to create a class to handle data accessing jobs.
Creating DAO Objects
For ease of maintenance, we used to create another Java class to handle data accessing jobs.
- Create
EventDAO.java
package events;
import java.util.Date;
import java.util.List;
import org.hibernate.Session;
import org.zkoss.zkplus.hibernate.HibernateUtil;
public class EventDAO {
Session currentSession() {
return HibernateUtil.currentSession();
}
public void saveOrUpdate(Event anEvent, String title, Date date) {
Session sess = currentSession();
anEvent.setTitle(title);
anEvent.setDate(date);
sess.saveOrUpdate(anEvent);
}
public void delete(Event anEvent) {
Session sess = currentSession();
sess.delete(anEvent);
}
public Event findById(Long id) {
Session sess = currentSession();
return (Event) sess.load(Event.class, id);
}
public List findAll() {
Session sess = currentSession();
return sess.createQuery("from Event").list();
}
}
- You have to compile the Java source, and place the class file in a directory called
classes
in the Web development folder, and in its correct package. (ex.$myApp/WEB-INF/classes/event/EventDAO.class
)
Accessing Persistence Objects in ZUML Page
To access persistence objects in ZUML page is simple, simply declare a persistence object, and uses it to get data from database.
- Create a
event.zul
in the root directory of web development. (ex.$myApp/event.zul
)
<zk>
<zscript><![CDATA[
import java.util.Date;
import java.text.SimpleDateFormat;
import events.Event;
import events.EventDAO;
//fetch all allEvents from database
List allEvents = new EventDAO().findAll();
]]></zscript>
<listbox id="lbxEvents">
<listhead>
<listheader label="Title" width="200px"/>
<listheader label="Date" width="100px"/>
</listhead>
<listitem forEach="${allEvents}" value="${each}">
<listcell label="${each.title}"/>
<zscript>String datestr = new SimpleDateFormat("yyyy/MM/dd").format(each.date);</zscript>
<listcell label="${datestr}"/>
</listitem>
</listbox>
</zk>
- Open a browser and visit the ZUML page. (ex.
http://localhost:8080/event/event.zul
)
Download
Download the sample