The web application that we are going to build is a DVD Store application that allows user to browse and rent out DVD titles. This tutorial shows how you can use hibernate as a persistence layer and interact with the DB containing some sample DVD title information. For the purpose of this tutorial, we will be using the Sakila DB, a sample DB that you can download from the MySQL site. Information for setting up the Sakila DB is provided in the following sections.
The following list enumerates the hibernate support in NetBeans IDE:
Perform the following tasks, from the console/command line:
mysql –u root –p <Enter MySQL root password. mysql> source <path-to-sakila-schema.sql> mysql> source <path-to-sakila-data.sql>
Sakila DB is now set up. For detailed instruction, refer to the MySQL Site. Once you have set up Sakila DB, from the NetBeans IDE, under Services tab, expand the Databases > MySQL Server at localhost:3306 node to find sakila entry as shown in the following figure:
![]() |
Right click on sakila entry and click Connect to allow NetBeans IDE to establish the connection with the DB.
![]() |
When you try to connect to Sakila DB, you will be prompted with a New Database Connection dialog box. Enter the MySQL connection information and click OK. If you are using WebStack in OpenSolaris OS, the default password for root is an empty string. For other platforms, provide the root password as applicable.
![]() |
When NetBeans successfully connects with the DB, You can see the connection entry jdbc:mysql://localhost:3306/sakila [root on Default schema] under the Databases node.
![]() |
You can browse the tables available in the DB by expanding the Tables node.
Now, we have successfully setup the DB for this tutorial. The next section deals with configuring NetBeans IDE to support Hibernate framework for web applications.
![]() |
Go to Services Tab and expand Servers node to verify if one of these servers is present. If you do not find any server, Go to Tools > Servers to add a server. If you are using OpenSolaris OS, you can install the complete AMP runtime and NetBeans IDE by downloading and installing the amp-dev IPS package.
Assuming that you have setup the tutorial environment, let us proceed with the project creation.
For creating a web application with Hibernate support, perform the following tasks:
![]() |
![]() |
![]() |
![]() |
Explore the DVDStore project tree. Hibernate configuration file hibernate.cfg.xml is created under Source Packages > <default package>. This is a simple XML file that you can edit at any stage of your project.
Here is the snippet of 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 name="session1">
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/sakila</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
</session-factory>
</hibernate-configuration>
In the above mentioned snippet, we have added an additional property:
<property name="hibernate.current_session_context_class">thread</property>
This is a required parameter to enable thread bound strategy for your hibernate configuration. For more information on Hibernate Sessions, read this document.
You can view the Hibernate configuration file using 2 views:
In this tutorial, we are not going to manually add properties to this file to keep it simple. You will notice later in the tutorial that whenever we create Hibernate mapping files, this configuration file gets automatically updated.
To create the Java class, perform the following tasks:
![]() |
Now that we have created the Film class, we need to add fields corresponding to the columns in the film table. You need not map all of the available columns in the table. Expand Source Packages > dvdrental to find the file Film.java. Make changes to the file as highlighted in the following snippet:
package dvdrental;
import java.io.Serializable;
public class Film implements Serializable {
private int filmID;
private String title;
private String description;
private String releaseYear;
private Integer languageID;
private Integer origLangID;
private Integer rentalDuration;
private Float rentalRate;
private Integer length;
private String rating;
private String specialFeatures;
private String lastUpdate;
}
Now you can add getters and setters for the fields. You don’t need to manually do this. Just right click on Film.java file and select Insert Code > Getters and Setters. Select all the check boxes and click Generate to generate the getters and setters for the variables.
![]() |
Now take a look at the modified file:
public class Film implements Serializable {
private int filmID;
private String title;
private String description;
private String releaseYear;
private Integer languageID;
private Integer origLangID;
private Integer rentalDuration;
private Float rentalRate;
private Integer length;
private String rating;
private String specialFeatures;
private String lastUpdate;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getFilmID() {
return filmID;
}
public void setFilmID(int filmID) {
this.filmID = filmID;
}
public Integer getLanguageID() {
return languageID;
}
public void setLanguageID(Integer languageID) {
this.languageID = languageID;
}
public String getLastUpdate() {
return lastUpdate;
}
public void setLastUpdate(String lastUpdate) {
this.lastUpdate = lastUpdate;
}
public Integer getLength() {
return length;
}
public void setLength(Integer length) {
this.length = length;
}
public Integer getOrigLangID() {
return origLangID;
}
public void setOrigLangID(Integer origLangID) {
this.origLangID = origLangID;
}
public String getRating() {
return rating;
}
public void setRating(String rating) {
this.rating = rating;
}
public String getReleaseYear() {
return releaseYear;
}
public void setReleaseYear(String releaseYear) {
this.releaseYear = releaseYear;
}
public Integer getRentalDuration() {
return rentalDuration;
}
public void setRentalDuration(Integer rentalDuration) {
this.rentalDuration = rentalDuration;
}
public Float getRentalRate() {
return rentalRate;
}
public void setRentalRate(Float rentalRate) {
this.rentalRate = rentalRate;
}
public String getSpecialFeatures() {
return specialFeatures;
}
public void setSpecialFeatures(String specialFeatures) {
this.specialFeatures = specialFeatures;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
In this section, we use the New File wizard to create a simple File.hbm.xml Hibernate mapping file for File.java class. You then need to edit the file in the XML editor to map the fields in the class to corresponding columns in the film table . You can use the IDE’ code completion feature to help you edit the mapping file.
To map film table to Film.java, perform the following tasks:
![]() |
![]() |
![]() |
![]() |
Just like the Hibernate configuration file, code completion is available for hibernate mapping file too.
The following figures show code completion feature for the hibernate mapping file:
![]() |
![]() |
Make changes to Film.hbm.xml file to map the fields as shown in the snippet below:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class dynamic-insert="false" dynamic-update="false" mutable="true" name="dvdrental.Film"
optimistic-lock="version" polymorphism="implicit" select-before-update="false" table="film">
<id column="film_id" name="filmID">
<generator class="increment"/>
</id>
<property column="description" name="description"/>
<property column="language_id" name="languageID"/>
<property column="last_update" name="lastUpdate"/>
<property column="length" name="length"/>
<property column="original_language_id" name="origLangID"/>
<property column="rating" name="rating"/>
<property column="release_year" name="releaseYear"/>
<property column="rental_duration" name="rentalDuration"/>
<property column="rental_rate" name="rentalRate"/>
<property column="special_features" name="specialFeatures"/>
<property column="title" name="title"/>
</class>
</hibernate-mapping>
In this section, we created a mapping file for the film table, but for our sample, we need to create similar mapping files for other Sakila tables including actor, category and language tables. We will use the reverse engineering feature available from NetBeans IDE 6.5 to map these tables as shown in the next section.
For creating a Hibernate reverse engineering file, perform the following tasks:
![]() |
![]() |
Now you need to choose the tables for which you need to map.
![]() |
![]() |
Now check your hibernate.cfg.xml file to see the mappings in place:
....
<mapping resource="dvdrental/Language.hbm.xml"/>
<mapping resource="dvdrental/Actor.hbm.xml"/>
<mapping resource="dvdrental/FilmActor.hbm.xml"/>
<mapping resource="dvdrental/FilmCategory.hbm.xml"/>
<mapping resource="dvdrental/Category.hbm.xml"/>
....
![]() |
The following code snippet shows the content of the HibernateUtil.java file. We won’t be modifying this file in this tutorial.
package dvdrental;
import org.hibernate.cfg.Configuration;
import org.hibernate.SessionFactory;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory from standard (hibernate.cfg.xml)
// config file.
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Log the exception.
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
For creating this helper class, perform the following tasks:
In the FilmHelper.java file, we will be adding helper methods to query the DB as shown in the following sections. Refer to the dvdrental/FilmHelper.java for the complete code.
In FilmHelper.java, add the following method:
public List getFilmTitles(int startID, int endID) {
List<Film> filmList = null;
try {
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery
("from Film as film where film.filmID between '"+startID+"' and '"+endID+"'");
filmList = (List<Film>) q.list();
} catch (Exception e) {
e.printStackTrace();
}
return filmList;
}
The example shown in the following snippet shows a sub query for fetching records from both actor and film_actor table:
public List getActorsByID(int filmID){
List<Actor> actorList = null;
try {
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery
("from Actor as actor where actor.actorID in
(select actorID from FilmActor filmActor where
filmActor.filmID='"+filmID+"')");
actorList = (List<Actor>) q.list();
} catch (Exception e) {
e.printStackTrace();
}
return actorList;
}
To invoke the HQL Editor, perform the following tasks:
![]() |
The following figure shows the HQL editor. The top panel contains the text area where you can build your HQL queries. For executing the query, click on the icon with a green arrow mark (next to the session field) as shown in the figure.
![]() |
You can also view the correponding SQL query by clicking the SQL button.
package dvdrental;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
public class FilmHelper {
Session session = null;
public FilmHelper() {
this.session = HibernateUtil.getSessionFactory().getCurrentSession();
}
public List getFilmTitles(int startID, int endID) {
List<Film> filmList = null;
try {
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery
("from Film as film where film.filmID between '"+startID+"' and '"+endID+"'");
filmList = (List<Film>) q.list();
} catch (Exception e) {
e.printStackTrace();
}
return filmList;
}
public List getActorsByID(int filmID){
List<Actor> actorList = null;
try {
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery
("from Actor as actor where actor.actorID in
(select actorID from FilmActor filmActor where filmActor.filmID='"+filmID+"')");
actorList = (List<Actor>) q.list();
} catch (Exception e) {
e.printStackTrace();
}
return actorList;
}
public Category getCategoryByID(int filmID){
List<Category> categoryList = null;
try {
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery
("from Category as category where category.categoryID in
(select categoryID from FilmCategory filmCat where filmCat.filmID='"+filmID+"')");
categoryList = (List<Category>) q.list();
} catch (Exception e) {
e.printStackTrace();
}
return categoryList.get(0);
}
public Film getFilmByID(int filmID){
Film film = null;
List<Film> filmList = null;
try {
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery
("from Film as film where film.filmID='"+filmID+"'");
filmList = (List<Film>) q.list();
film = (Film) filmList.get(0);
} catch (Exception e) {
e.printStackTrace();
}
return film;
}
public String getLangByID(int langID){
String language = null;
List<Language> langList = null;
try {
org.hibernate.Transaction tx = session.beginTransaction();
Query q = session.createQuery
("from Language as lang where lang.languageID='"+langID+"'");
langList = (List<Language>) q.list();
language = ((Language) langList.get(0)).getLanguage();
} catch (Exception e) {
e.printStackTrace();
}
return language;
}
}
We will be invoking the methods in this class from the JSP files we build in the next section.
To create the JSP file, perform the following tasks:
In browse.jsp file add the following snippet:
<%
//Get title ID
int filmID = 1;
if (request.getParameter("id") != null) {
filmID = Integer.parseInt(request.getParameter("id"));
}
%>
<%
boolean startPage = false;
boolean endPage = false;
FilmHelper helper = new FilmHelper();
Film film = helper.getFilmByID(filmID);
String filmTitle = film.getTitle();
String filmDescription = film.getDescription();
//Get Actors
List actors = helper.getActorsByID(filmID);
StringBuffer totalCast = new StringBuffer();
//Get Category
Category category = helper.getCategoryByID(filmID);
String catName = category.getName();
for(int i=0;i<actors.size();i++){
Actor actor = (Actor)actors.get(i);
totalCast.append(actor.getFirstName());
totalCast.append(" ");
totalCast.append(actor.getLastName());
totalCast.append(" ");
}
int langID = film.getLanguageID();
String language = helper.getLangByID(langID);
int filmLength = film.getLength();
String filmRating = film.getRating();
String filmYear = film.getReleaseYear();
int rentalDuration = film.getRentalDuration().intValue();
float rentalRate = film.getRentalRate().floatValue();
String specialFeatures = film.getSpecialFeatures();
…..
%>
Check the source of index.jsp for the complete code. Also this tutorial does not show you how to create Style sheets (CSS). Download the tutorial bundle and check out these files.
Also check out the code of index.jsp that displays the available DVDs.
If the web browser does not start automatically, access the application at:
http://localhost:8080/DVDStore/
The following figure shows the main page. Click any title to view the DVD information.
Detailed information about the DVD is displayed on this page. Click Rent Out to rent out the DVD.
![]() |
In hibernate.cfg.xml, you need to modify the MySQL connection information to make the application work.
| DVDStore.zip | ![]() |
4204799 bytes |
| dvdstore1.PNG | ![]() |
27385 bytes |
| dvdstore2.PNG | ![]() |
19043 bytes |
| hbmaid1.png | ![]() |
22358 bytes |
| hbmaid2.png | ![]() |
42986 bytes |
| hiberutil.png | ![]() |
40875 bytes |
| hqleditor1.png | ![]() |
26842 bytes |
| hqleditor2.png | ![]() |
31860 bytes |
| mapping1.png | ![]() |
44683 bytes |
| mapping2.png | ![]() |
33423 bytes |
| mapping3.png | ![]() |
18684 bytes |
| mapping4.png | ![]() |
34485 bytes |
| nb65_newconfig.png | ![]() |
38040 bytes |
| nb65_newmapping.png | ![]() |
38065 bytes |
| nb65_newreverse.png | ![]() |
38343 bytes |
| nb65_newreverse2.png | ![]() |
29027 bytes |
| nb65_newreverse3.png | ![]() |
31608 bytes |
| nb65_newreverse4.png | ![]() |
32158 bytes |
| nb65_newutil.png | ![]() |
38410 bytes |
| nb65_plugin1.png | ![]() |
32508 bytes |
| newproject1.png | ![]() |
46676 bytes |
| newproject2.png | ![]() |
43849 bytes |
| newproject3.png | ![]() |
36642 bytes |
| newproject4.png | ![]() |
45530 bytes |
| plugin_install.png | ![]() |
56800 bytes |
| plugin_install2.png | ![]() |
20773 bytes |
| pojo1.png | ![]() |
31969 bytes |
| pojo2.png | ![]() |
19702 bytes |
| prereq1.png | ![]() |
38672 bytes |
| sakila_nbview1.png | ![]() |
20260 bytes |
| sakila_nbview2.png | ![]() |
21452 bytes |
| sakila_nbview3.png | ![]() |
22119 bytes |
| sakila_nbview4.png | ![]() |
20228 bytes |