Saturday, October 18, 2008

Hibernate Configuration and Setup with Eclipse, mySQL and Tomcat Step 16C

The other type of database connection is to use Hibernate. Hibernate is a xml mapping tool that allows you to map your Java objects to the database.

Make sure you have installed your database driver.  In this tutorial, it is the mysql database driver.  See my prior posts for download information.  Also, make sure you have created the user name and password used to connect.  See my prior posts for information.
**********************
Hibernate Jar files
**********************
First, you should download the appropriate jar files. See my prior posts for download information.

Apply your hibernate3.jar file to your project lib directory. In the hibernate download you will find a folder called required. All of those jar files should also be copied over to your lib folder.

Under the optional folder in the hibernate download you will see a folder called c3po. Copy that jar file into your lib directory as well.

There are a couple of jar files that are not included in the hibernate download that you will need.
Visit this site: slf4j

There is a jar file missing in the hibernate version of the slf4j. download the same version of the slf4j.jar file that you downloaded with hibernate. That would be version 1.4.2 if you are using hibernate3. You will need to locate the slf4j-log4j12-1.4.2.jar file and copy that in your lib directory. That file is missing from the hibernate version.

You should also visit this site:
log4j
Download apache-log4j-1.2.15 for hibernate3 and apply the log4j-1.2.15.jar file to your project lib directory.

You should set the eclipse build path to the hibernate3.jar file in eclipse.

*****************
The hibernate.xml files
*****************
You need to create a xml file to establish the connection to the database.
In your WEB-INF folder in your project, create a file called user.hibernate.cfg.xml. That is the name I will be calling my configuration file for this tutorial.


Copy the below code into that file.


user.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>
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/catalog</property>
<property name="hibernate.connection.username">UserBook</property>
<property name="hibernate.connection.password">UserBook123</property>
<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
<property name="hibernate.show_sql">false</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.cglib.use_reflection_optimizer">false</property>
<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.idle_test_period">3000</property> <!-- seconds -->
<property name="hibernate.c3p0.max_size">100</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.min_size">10</property>
<property name="hibernate.c3p0.timeout">100</property>
<property name="hibernate.c3p0.testConnectionOnCheckout">true</property>
<mapping resource="com/vo/Users.xml" />
</session-factory>
</hibernate-configuration>

The first set of property values is establishing the connection to the database just like you would with the JDBC connection. The second set of property values is using the c3p0.jar file to manage your connections to the database. This is very important because without this code, your connection pool will run out and might crash your system.


The mapping resources are your object mappings. You will need to list all of your object mappings in this file. In our case we are going to create a Users.xml file to map the Users object to the Users table in the mysql database.


Create a package called com.vo and in that package create a class called Users.java and Users.xml.
Paste the following code into those files.


Users.java

package com.vo;

public class Users implements java.io.Serializable{

private static final long serialVersionUID = 4391395677185754011L;
String name;
Integer id;
public Integer getId()
{
return id;
}
public void setId(Integer id)
{
this.id=id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
}





Users.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">
<!-- Generated Oct 27, 2006 11:49:56 AM by Hibernate Tools 3.2.0.beta8 -->
<hibernate-mapping>
<class name="com.vo.Users" table="users" >
<id name="id" column="Id" type="java.lang.Integer" >
<generator class="increment"/>
</id>
<property name="name" type="java.lang.String">
<column name="FirstName" length="50" />
</property>
</class>
</hibernate-mapping>



The Users.java class is just a regular Java bean with setter and getter methods for the name and id. The Users.xml file is mapping the id from the database to the Users class and the firstname from the database to the Users class.

Now you need to make sure these xml files appear in the correct place in the war file. You should add some code to your build file.


Add the following line to your variable list in your build.xml file. Use this code if you are using the build.xml example I have in my previous posts.
<property name="HIBERNATE" value="${CONTENT_DIR}/WEB-INF" />


This code defines a variable that points to your WEB-INF folder called HIBERNATE.

In my build.xml file I added some code to include the xml mappings within the war file. (See below)

You need the user.hibernate.cfg.xml file to be in the classes directory and the Users.xml file to be located in the same location as the Users.class file.


Add to build.xml in jar file target to copy xml files (put it right where you are copying the jar file).

<copy todir="${JAVA_BUILD_DIR}">
<fileset dir="${HIBERNATE}/">
<include name="*user.hibernate.cfg.xml" />
</fileset>
</copy>
<copy todir="${JAVA_BUILD_DIR}/com/vo/">
<fileset dir="${JAVA_SRC_DIR}/com/vo/">
<include name="*.xml" />
</fileset>
</copy>
This code will put the User.xml file in your class directory, and the user.hibernate.cfg.xml file in your WEB-INF classes directory.




************************
Create a Listener and Test Hibernate Connection
************************
I am now going to create a hibernate listener that will establish the hibernate session.

In your web.xml file add the following listener.


Add listener to web.xml

<listener>
<listener-class>com.hibernate.init.UserHibernateListener</listener-class>
</listener>



Now we need to create the listener. In your project create a package called com.hibernate.init and in that package create a class called UserHibernateListener. This listener will create the hibernate session.


In the UserHibernateListener class copy the following code:


UserHibernateListener.java
package com.hibernate.init;

import javax.servlet.ServletContextEvent;
import com.util.HibernateUtil;

public class UserHibernateListener{
/**
* Creates Hibernate's Session Factory.
*
* @param
* @return void
* @see
*/
public void contextInitialized(ServletContextEvent event) {
//Just call the static initializer of that class
HibernateUtil.getSessionFactory();
System.out.println("Hibernate is successfully created");
}

/**
* Closes Hibernate's Session Factory.
*
* @param
* @return void
* @see
*/
public void contextDestroyed(ServletContextEvent event) {
//Free all resources
HibernateUtil.getSessionFactory().close();
}
}


I am also going to create a HibernateUtil that will manage my hibernate session.


Create another package called com.util and create a class in that package called HibernateUtil.java.


Paste the following code in that class.


HibernateUtil.java
package com.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* This class is intended to be a utilarian class for Hibernate related activities.
* Currently this class has a method for getting SessionFactory.
* @author Greg Dias
*/
public class HibernateUtil {
/**
* An instance variable to hold reference to the Hibernate's Session Factory for ESC db.
*/
private static final SessionFactory sessionFactory;

/**
* A static block to initialize the Hibernate's Session Factory for ESC db and
* store it in instance variable.
*/
static {
try {
// Create the SessionFactory from hibernate.cfg.xml
sessionFactory = new Configuration().configure("user.hibernate.cfg.xml")
.buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed."+ ex);
throw new ExceptionInInitializerError(ex);
}
}
/**
* Gets the Hibernate's Session Factory, based on given parameter.
*
* @param String type of SessionFacgtory (DB) required.
* @return org.hibernate.SessionFactory
* @see
*/
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
Possible Errors:
org.hibernate.exception.SQLGrammarException: This error means that your mappings are incorrect. Make sure that your mappings are named correctly and you aren't missing any tags.

Now it is time to test your connection to see if everything is configured correctly.


Add the following code to your UserAction setUser method or any method that you will be using to test your configuration.


Test Code
HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
List<User> results=null;
try {
SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
System.out.println("creating session factory");
results= sessionFactory.getCurrentSession().createCriteria(
Users.class).list();
System.out.println("creating user list");
HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().commit();
System.out.println("commiting transaction");
} catch (RuntimeException re) {
System.out.println("Error "+ re.toString());
throw re;
}
System.out.println("printing list");
if(results!=null)
{
for(Users user:results)
{
System.out.println("Name of User: " +users.getName());
}
}

Build your project and then start Tomcat. Go to your http://localhost:8080/UserBook/ project and test the code you just added to see if your hibernate connection works.
When you run the test code, the name from the user table should print in the console. If that is the case, then you have successfully configured hibernate and mapped one object to one table in the database. We only mapped one column in this example to make sure you get a connection. In my next posts I will show you how to finish your mappings to the database.



Reverse Engineer Hibernate Mappings Step 17

1 comments:

Mylene September 20, 2010 11:21 PM  

This is a great tutorial. But it would be better if there is a screen capture of the file structure to make sure that the reader is on the right track.