Thursday, October 30, 2008

Creating Hibernate DAO Object Using the Factory Method Step 18

In my prior examples I had you test your database connections within your action class. You do not want to access your database directly from your action class. It is a better design to have a form of abstraction and encapsulation which will access your data source. Therefore, I am going to explain how to set up your hibernate connection using a Data Access Object (DAO) using the factory method. You should remove any access directly to the database in your action class.

DAO:
The DAO object implements the access mechanism required to work with your data source. In this case our data source is the mySQL database. The DAO completely hides the data source implementation details from its clients. The DAO will act as an adaptor between the components and the data source. It is not necessary for any other part of the application to know about the data source.

Factory Method:
One of the goals of object-oriented design is to delegate responsibility among the different objects. This encourages Encapsulation and Delegation which is a key component in object orientation. The solution to forcing Encapsulation is to use the factory method. This also can be used in the singleton pattern which is a design patter that is used to restrict instantiation of a class to one object. This concept is useful when exactly one object is needed to coordinate actions across the system.

In your UserBook project, create a package called com.dao and in that package you should create a class called UserBookDAO.java. The UserBookDAO is the class that will access your database.

Create a package called com.serviceImpl and in that package create a class called UserBookServiceImpl.java and UserBookService.java. The UserBookServiceImpl class will be the implementation and the UserBookService will be the interface.

Create another package called com.serviceFactory and create a class in that package called ServiceFactory.

After you have created your value object mappings, there are some possible issues you might have received.

Possible Issues:

1) failed.org.hibernate.MappingException: entity class not found: Book

This issue is because the mappings need to declare the full package. See below.

2) javax.servlet.ServletException: failed to lazily initialize a collection of role

This issue is because your sets need to say lazy=false.

Here is some more information concerning lazily initialization-
Non-lazy initialization retrieves an object and all of its related objects at load time. This can result in hundreds if not thousands of select statements when retrieving one entity. The problem is compounded when bi-directional relationships are used, often causing entire databases to be loaded during the initial request. Of course one could tediously examine each object relationship and manually remove those most costly, but in the end, we may be losing the ease of use benefit sought in using the ORM tool. The obvious solution is to employ the lazy loading mechanism provided by hibernate. This initialization strategy only loads an object's one-to-many and many-to-many relationships when these fields are accessed. The scenario is practically transparent to the developer and a minimum amount of database requests are made, resulting in major performance gains.
http://www.blogjava.net/vince/archive/2006/11/27/83850.html

Updates:
In this tutorial you need to make sure you have updated the following:
1) Make sure all of your mappings are in the com.vo package and are included in your War file. Make sure your build.xml copies them correctly. See my prior posts for more information.

2) You need to make sure your user.hibernate.cfg.xml file includes all of your mappings:
<mapping resource="com/vo/Users.hbm.xml" />
<mapping resource="com/vo/Book.hbm.xml" />
<mapping resource="com/vo/Bookcategory.hbm.xml" />

3) Make sure you have data in the database to test your system

4) In the Users.hbm.xml file, change the name="Users" to be name="com.vo.Users".
Where it says entity-name="Book", change that to entity-name="com.vo.Book".
Where it says set name="books", change it to:
set name="books" lazy="false"

5) In the Bookcategory.hbm.xml, change the name="com.vo.Bookcategory" and change
one-to-many class="Book" to
one-to-many class="com.vo.Book"
and change
set name="books" to
set name="books" lazy="false"

6) In the Book class change
name="Book" to
name="com.vo.Book" and change
class="Bookcategory" to
class="com.vo.Bookcategory" and change
set name="userses" inverse="false" to
set name="userses" inverse="false" lazy="false"
and change
entity-name="Users" to
entity-name="com.vo.Users"

The below are the particular class information from the new classes you created:

UserBookDAO.java




package com.dao;
import java.util.List;
import org.hibernate.SessionFactory;
import com.util.HibernateUtil;
import com.vo.Book;
import com.vo.Bookcategory;
import com.vo.Users;
public class UserBookDAO {
public List<Book> getBooks()
{
HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
List<Book> results=null;
try {
SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
results= sessionFactory.getCurrentSession().createCriteria(
Book.class).list();
HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().commit();
} catch (RuntimeException re) {
System.out.println("Error In Hibernate getBooks" re.toString());
throw re;
}
return results;
}
public List<Bookcategory> getBookCategory()
{
HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
List<Bookcategory> results=null;
try {
SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
results= sessionFactory.getCurrentSession().createCriteria(
Bookcategory.class).list();
HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().commit();
} catch (RuntimeException re) {
System.out.println("Error In Hibernate getBookCategory" re.toString());
throw re;
}
return results;
}
public List<Users> getUsers()
{
HibernateUtil.getSessionFactory().getCurrentSession().beginTransaction();
List<Users> results=null;
try {
SessionFactory sessionFactory=HibernateUtil.getSessionFactory();
results= sessionFactory.getCurrentSession().createCriteria(
Users.class).list();
HibernateUtil.getSessionFactory().getCurrentSession().getTransaction().commit();
} catch (RuntimeException re) {
System.out.println("Error In Hibernate getUsers" re.toString());
throw re;
}
return results;
}
public Book getOneBook(String id)
{ //will be completed later
return null;
}
public Users getOneUser(String id)
{
//will be completed later
return null;
}
}




This class will manage the connection to your database. To test your services, we have methods to get a list of books, users and book categories. We will fill in the other methods later.

UserBookServiceImpl.java




package com.serviceImpl;
import java.util.List;
import com.dao.UserBookDAO;
import com.vo.Book;
import com.vo.Bookcategory;
import com.vo.Users;
public class UserBookServiceImpl implements UserBookService{
UserBookDAO dao=new UserBookDAO();
public List getBooks()
{
return dao.getBooks();
}
public List getBookCategory()
{
return dao.getBookCategory();
}
public List getUsers()
{
return dao.getUsers();
}
public Book getOneBook(String id)
{
return dao.getOneBook(id);
}
public Users getOneUser(String id)
{
return dao.getOneUser(id);
}
}



This class will be the layer that will access the DAO object. This will be the class that you use to access the data you will need.

UserBookService.java




package com.serviceImpl;
import java.util.List;
import com.vo.Book;
import com.vo.Bookcategory;
import com.vo.Users;
public interface UserBookService {
public List getBooks();
public List getBookCategory();
public List getUsers();
public Book getOneBook(String id);
public Users getOneUser(String id);
}




This is the interface used by the UserBookServiceImpl class.

ServiceFactory.java




package com.serviceFactory;
import com.serviceImpl.UserBookService;
import com.serviceImpl.UserBookServiceImpl;
public class ServiceFactory {
private static final ServiceFactory serviceFactory=new ServiceFactory();
private ServiceFactory()
{
}
public static ServiceFactory getInstance(){
return serviceFactory;
}
public UserBookService getUserBookService(){
return new UserBookServiceImpl();
}
}




This is the factory class that will be used to instantiate one instance of the service layer. You will always use the factory to retrieve the services when you need to access the database.

UserAction.java to test your connections and service layer.




package com.action;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import com.serviceFactory.ServiceFactory;
import com.serviceImpl.UserBookService;
import com.vo.Book;
import com.vo.Bookcategory;
import com.vo.Users;
public class UserAction extends DispatchAction {
public ActionForward forwardToUser(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
System.out.println("in forwardToUser");
return mapping.findForward("success");
}
public ActionForward setUser(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
UserBookService service = ServiceFactory.getInstance().getUserBookService();
List<User> userList=service.getUsers();
for(Users user:userList)
{
System.out.println("Name of User: "+user.getFirstName()+" "+user.getLastName());
Set userBook=user.getBooks();
ArrayList<Book> userBookList=new ArrayList(userBook);
for(Book userbook:userBookList)
{
System.out.println("The users name of their book "+userbook.getBookName());
System.out.println("The users author of their book "+userbook.getBookAuthor());
}
}
//make sure you insert data using mysqlog into categoryList<Bookcategory> categoryList=service.getBookCategory();
for(Bookcategory category:categoryList)
{
System.out.println("Name of Category: "+category.getCategory());
}
List<Book> bookList=service.getBooks();
for(Book book:bookList)
{
System.out.println("Name of Book: "+book.getBookName());
}
return mapping.findForward("success");
}
}




If you set everything up correctly, visit your local host and submit your form and you should see the list of your data printing out in your eclipse console.

Go to Step 19 to see how to save objects and retrieve individual objects based on the id.

Go To Step 19

Read more...

Thursday, October 23, 2008

Comodo Trusted Internet Manifesto

Are you tired of the insecurity of the internet? There are so many ways people can steal your information when you are using an unsecured internet. There is a company called COMODO that are in the process of building a trusted internet. Comodo is a well-respected internet security company, selling the digital certificates that make it possible for online businesses to operate on secure socket layers. If you have an internet transaction with one of these businesses, the digital certificate and secure socket layer keep your information private.They want everybody to experience the Internets power anywhere in the world on a trusted and secured internet.

This company is combining security and authentication technologies to shape people’s trust in the internet. Already they have over 250,000 businesses and millions of consumers benefiting from their technology. They encompass encryption, digital certification, identity and access services, and even desktop security solutions. They are the leading company in the fight to make the internet secure.

If you own a business or if you are a consumer and you are interested in the design, development and deployment of enterprise security services, you should check out Comodo’s Trusted Internet Manifesto. Through their services, they can assist their customers in design, planning and deployment of security to increase the security of your business. They have appointed Dr. Colin Walter to head up their cryptography department which has increased their awareness in the world of cryptography. So what are you waiting for? You should visit their website now to get more information on the security of your business.

Read more...

Monday, October 20, 2008

Reverse Engineer Hibernate Value Object Mappings hbm.xml Examples Step 17

Reverse Engineer your Hibernate Mappings

********************************************
If you already have the database built, you can reverse engineer to create your value objects and your hibernate mappings. This will save you time in creating each of your value objects and mappings manually.

Eclipse has some tools to accomplish this. I used the openlogic plugin.
You should visit this website: https://openlogic.com/packages/eclipseplugin-hibernate_tools to retrieve the plugin.

This website is https so you will have to bypass the security warning.

You should download the openlogic-eclipseplugin-hibernate_tools-3.2.1.GA-all-bin-1.zip

Make sure you have the mysql.jar file you in your lib directory with the eclipse build path pointing to it. The eclipse plugin will need this to connect to the database.

When you download the plugin, you should unzip it and copy all of the directories and jar files from the plugins directory to the eclipse plugin directory.

**************************************************
There are a couple of possible errors you can receive when using this plugin.
**************************************************

1) java.lang.ClassNotFoundException: org.eclipse.jface.viewers.BaseLabelProvider

This error is because you are using an older version of eclipse. You will need to upgrade to a more current version of eclipse to use this plugin.

2) java.lang.ClassNotFoundException: org/eclipse/ui/internal/util/SWTResourceUtil

This error is because you are using a version of Ganymede Eclipse which is missing this class. You will need to add this class by following these steps:

2a) You need to get this class from an older version of Eclipse. I used the eclipse version 3.2.2. You should download this version or another version and locate this file in the eclipse plugin directory. org.eclipse.ui.workbench*.jar.


2b) Unzip this jar file and remove the SWTResourceUtil.class file.


2c) Locate the org.eclipse.ui.workbench_*.jar in your current eclipse directory. You should change the extension from jar to zip and then unzip it. Drop the class in the org/eclipse/ui/internal/util folder. Then zip it back up and change the extension back to .jar and place the jar file back in the plugin directory of eclipse.

3) Missing sun.nio.cs.surrogate

This error means that you didn't copy all of the jar files from the plugin into eclipse.
***********************************************

After you have the plugin installed, then restart eclipse.
From my prior posts you should have already established a connection to the database using Hibernate.

After opening up eclipse, select windows->open perspective->other. Select Hibernate from the menu.

In the Hibernate Configuration window, select the right mouse button and select configuration.

Project: select the project you are working on.
Property file: If you are using a properties file, select it from here.
Configuration File: You need to select the configuration file that holds your database information.

Apply the changes.

Now we want to create your mappings directly from the database.

You should be able to select the database and see all the tables that you are using in your project from your configuration information in your hibernate mappings.

At the top menu you will see a drop down where you are able to select Hibernate Code Generation and Configuration. Select it to generate your mapping files.

On the Hibernate Code Generation link on the left, you should select the right mouse button and select new to open the configuration page.

In the Console Configuration, select hibernate.

Select what output directory you want to use. This is the directory where the mappings will be copied too. You should put them in the com.vo package which is the package holding your value objects.

Select the reverse enginner check box.

You can put the package in the configuration also and that will set the proper package name for the mappings.  Put the directory as the src directory and the tool will create the package for you.

You should select the exporters tab and select the Hiberante XML Mappings check box and Domain code.

You should press apply and then run to generate your mappings.

If you were unable to get the reverse engineering to work, then below I have the files you will need for this tutorial. If you do not reverse engineer, you can create the mappings manually.


If you reverse engineer, you will need to make sure you update the java objects to be the correct packages. You should also add a serializable variable "private static final long serialVersionUID=123l;" to each value object class.


***************************
VO Objects and Mappings
***************************


Book.java




package com.vo;
// Generated Oct 21, 2008 7:43:57 PM by Hibernate Tools 3.2.1.GA

import java.util.HashSet;
import java.util.Set;

/**
* Book generated by hbm2java
*/
public class Book implements java.io.Serializable {

private static final long serialVersionUID=123l;
private long id;
private Bookcategory bookcategory;
private String bookName;
private String bookAuthor;
private String bookPublisher;
private Set userses = new HashSet(0);

public Book() {
}

public Book(long id) {
this.id = id;
}

public Book(long id, Bookcategory bookcategory, String bookName,
String bookAuthor, String bookPublisher, Set userses) {
this.id = id;
this.bookcategory = bookcategory;
this.bookName = bookName;
this.bookAuthor = bookAuthor;
this.bookPublisher = bookPublisher;
this.userses = userses;
}

public long getId() {
return this.id;
}

public void setId(long id) {
this.id = id;
}

public Bookcategory getBookcategory() {
return this.bookcategory;
}

public void setBookcategory(Bookcategory bookcategory) {
this.bookcategory = bookcategory;
}

public String getBookName() {
return this.bookName;
}

public void setBookName(String bookName) {
this.bookName = bookName;
}

public String getBookAuthor() {
return this.bookAuthor;
}

public void setBookAuthor(String bookAuthor) {
this.bookAuthor = bookAuthor;
}

public String getBookPublisher() {
return this.bookPublisher;
}

public void setBookPublisher(String bookPublisher) {
this.bookPublisher = bookPublisher;
}

public Set getUserses() {
return this.userses;
}

public void setUserses(Set userses) {
this.userses = userses;
}

}




Book.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"> <!-- Generated Oct 21, 2008 7:44:22 PM by Hibernate Tools 3.2.1.GA --> <hibernate-mapping> <class name="Book" table="book" catalog="catalog"> <id name="id" type="long"> <column name="Id" /> <generator class="assigned" /> </id> <many-to-one name="bookcategory" class="Bookcategory" fetch="select"> <column name="BookCategoryId" /> </many-to-one> <property name="bookName" type="string"> <column name="BookName" length="50" /> </property> <property name="bookAuthor" type="string"> <column name="BookAuthor" length="50" /> </property> <property name="bookPublisher" type="string"> <column name="BookPublisher" length="50" /> </property> <set name="userses" inverse="false" table="userbook"> <key> <column name="BookId" not-null="true" /> </key> <many-to-many entity-name="Users"> <column name="UserId" not-null="true" /> </many-to-many> </set> </class> </hibernate-mapping>

Users.java

package com.vo;
// Generated Oct 21, 2008 7:43:57 PM by Hibernate Tools 3.2.1.GA

import java.util.HashSet;
import java.util.Set;

/**
* Users generated by hbm2java
*/
public class Users implements java.io.Serializable {
private static final long serialVersionUID=123l;
private long id;
private String firstName;
private String lastName;
private String middleName;
private String email;
private Set books = new HashSet(0);

public Users() {
}

public Users(long id) {
this.id = id;
}

public Users(long id, String firstName, String lastName, String middleName,
String email, Set books) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.middleName = middleName;
this.email = email;
this.books = books;
}

public long getId() {
return this.id;
}

public void setId(long id) {
this.id = id;
}

public String getFirstName() {
return this.firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return this.lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getMiddleName() {
return this.middleName;
}

public void setMiddleName(String middleName) {
this.middleName = middleName;
}

public String getEmail() {
return this.email;
}

public void setEmail(String email) {
this.email = email;
}

public Set getBooks() {
return this.books;
}

public void setBooks(Set books) {
this.books = books;
}

}



Users.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"> <!-- Generated Oct 21, 2008 7:44:22 PM by Hibernate Tools 3.2.1.GA --> <hibernate-mapping> <class name="Users" table="users" catalog="catalog"> <id name="id" type="long"> <column name="Id" /> <generator class="assigned" /> </id> <property name="firstName" type="string"> <column name="FirstName" length="50" /> </property> <property name="lastName" type="string"> <column name="LastName" length="50" /> </property> <property name="middleName" type="string"> <column name="MiddleName" length="50" /> </property> <property name="email" type="string"> <column name="Email" length="50" /> </property> <set name="books" inverse="false" table="userbook"> <key> <column name="UserId" not-null="true" /> </key> <many-to-many entity-name="Book"> <column name="BookId" not-null="true" /> </many-to-many> </set> </class> </hibernate-mapping>

Bookcategory.java

package com.vo;
// Generated Oct 21, 2008 7:43:57 PM by Hibernate Tools 3.2.1.GA

import java.util.HashSet;
import java.util.Set;

/**
* Bookcategory generated by hbm2java
*/
public class Bookcategory implements java.io.Serializable {
private static final long serialVersionUID=123l;
private long id;
private String category;
private Set books = new HashSet(0);

public Bookcategory() {
}

public Bookcategory(long id) {
this.id = id;
}

public Bookcategory(long id, String category, Set books) {
this.id = id;
this.category = category;
this.books = books;
}

public long getId() {
return this.id;
}

public void setId(long id) {
this.id = id;
}

public String getCategory() {
return this.category;
}

public void setCategory(String category) {
this.category = category;
}

public Set getBooks() {
return this.books;
}

public void setBooks(Set books) {
this.books = books;
}

}








Bookcategory.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"> <!-- Generated Oct 21, 2008 7:44:22 PM by Hibernate Tools 3.2.1.GA --> <hibernate-mapping> <class name="Bookcategory" table="bookcategory" catalog="catalog"> <id name="id" type="long"> <column name="Id" /> <generator class="assigned" /> </id> <property name="category" type="string"> <column name="Category" length="50" /> </property> <set name="books" inverse="true"> <key> <column name="BookCategoryId" /> </key> <one-to-many class="Book" /> </set> </class> </hibernate-mapping>



After you have created all of your mappings, their are some possible issues that you will have to fix. See my next post for creating a DAO object and fixing any possible issues.

Go To Step 18







Read more...

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

Read more...

Saturday, October 11, 2008

Database Connection Tomcat Server 5.0 and 5.5 Step 16B

Connecting to the database using a Tomcat server is done differently depending on which version of Tomcat you are using. I found it to be easier with version 5.0. For both of them, you need to make sure you have the mySQL jar file in the common/lib directory of Tomcat or the jar file for any other database you are attempting to work with.

You can download the mySQL jar file from this site:
http://dev.mysql.com/downloads/connector/j/5.1.html
***********************************
Connect To mySQL with
Tomcat 5.0
***********************************

You need to create a xml file in your Tomcat/conf/Catalina/localhost directory.
You will need to name it the same name as the war file that you deploy.


In our case we will call it UserBook.xml.

Paste the following code into this file.

UserBook.xml


<?xml version='1.0' encoding='utf-8'?>
<Context docBase="UserBook"
path="/UserBook" reloadable="true">
<Resource name="jdbc/catalog"
type="
javax.sql.DataSource"/>
<ResourceParams name="jdbc/catalog">
<parameter>
<name>url</name>
<value>jdbc:mysql://localhost/catalog</value>
</parameter>

<parameter>
<name>maxIdle</name>
<value>5</value>
</parameter>

<parameter>
<name>removeAbandoned</name>
<value>true</value>
</parameter>

<paramenter>
<name>removeAbandonedTimeout</name>
<value>300</value>
</paramenter>

<parameter>
<name>maxActive</name>
<value>-1</value>
</parameter>

<parameter>
<name>driverClassName</name>
<value>com.mysql.jdbc.Driver</value>
</parameter>

<parameter>
<name>maxWait</name>
<value>10000</value>
</parameter>

<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory<
/value>
</parameter>

<parameter>
<name>username</name>
<value>UserBook</value>
</parameter>

<parameter>
<name>password</name>
<value>UserBook123</value>
</parameter>

</ResourceParams>


</Context>


The docBase should be the name of the war file that is deployed. The path is the path of the war file directory. The resource name is the name you will use in your code to access this connection. You need to properly set your parameters. The url is the location of the database. In our case, we are accessing the database on our local machine and the database name is catalog. You set other parameters such as removeAbandoned which removes the abandoned connections to the database which is important. You also should put the database username and the database password.

***********************************
Configure to Connect To mySQL
with Tomcat 5.5
***********************************


You need to create a xml file in your Tomcat/conf/Catalina/localhost directory.
You will need to name it the same name as the war file that you deploy.
In our case, we will call it UserBook.xml. Paste the following code into this file. This will create a global connection pool for all of your applications.

UserBook.xml


<?xml version='1.0' encoding='utf-8'?>
<Context docBase="${Catalina_Home}/webapps/UserBook"
privileged="true" antiResourceLocking="false"
antiJARLocking="false" >
<Resource name="jdbc/catalog" auth="Container"
type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/catalog?autoReconnect=true"
username="UserBook" password="UserBook123"
maxActive="20" maxIdle="10" maxWait="-1"/> <
ResourceLink name="jdbc/catalog" global="jdbc/catalog"
type="javax.sql.DataSource" /> </Context>





You use the variable {Catalina_Home} to get to the location of your project.
The ResourceLink is linking your UserBook application to your data connection
in your server.xml file.

In your Tomcat/conf folder you should see a file called server.xml.
Open this file up and paste the following code under the
globalnamingresources tag.

Add to server.xml


<Resource name="jdbc/catalog" auth="Container"
type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/catalog?autoReconnect=true"
username="UserBook" password="UserBook123" maxActive="20"
maxIdle="10" maxWait="-1"/>



Make sure the username and password are correct and the resource name
is the same name as the resource name in your UserBook.xml
folder in your tomcat/catalina/localhost directory.

Add this to your web.xml file in your project WEB-INF folder under the servlet tag.


<resource-ref> <description>DB Connection</description> <res-ref-name>jdbc/catalog</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>



***********************************
Code in both versions of Tomcat to
access the database connections.
***********************************


I create a package in my project called com.util and there I put a class called JDBCManager. This is the class I will use to create my database connection.

JDBCManager.java



package com.util;

import java.sql.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
/**
* Written by Greg Dias
*
* Purpose: This class is used to connect to a database using
* a JDBC connection.
*/
public class JDBCManager
{
private String connectionName;
private Connection connection;
private String query;
public JDBCManager()
{
connectionName = "";
connection = null;
query = "";
}
/**
* Purpose: Will need to set the JDBC Name
* according to the name from the application
* web.xml file.
* @param name
*/
public void setJDBCName(String name)
{
connectionName = name;
}
/**
* Purpose: Should be called to setup the connection.
* @throws Exception
*/
public void setUp()
throws Exception
{
try
{
Context ctx = new InitialContext();
if(ctx == null)
throw new Exception("Boom - No Context");
DataSource ds = (DataSource)ctx.lookup((new StringBuilder()).append("java:comp/env/").append(connectionName).toString());
if(ds != null)
connection = ds.getConnection();
ctx.close();
}
catch(Exception e)
{
throw new Exception((new StringBuilder()).append("Error in setUp").append(e).toString());
}
}
/**
* Purpose: Is used to set the query.
* @param query
*/
public void setQuery(String query)
{
this.query = query;
}
/**
* Purpose: Returns the result set that contains the data
* from the query.
* @return ResultSet
* @throws Exception
*/
public ResultSet getSet()
throws Exception
{
ResultSet rst = null;
try
{
if(connection != null)
{
Statement stmt = connection.createStatement();
rst = stmt.executeQuery(query);
}
}
catch(Exception e)
{
throw new Exception((new StringBuilder()).append("Error getting Result Set").append(e).toString());
}
return rst;
}
/**
* Purpose: Executes the query without returning a result set.
* @throws Exception
*/
public void execute()
throws Exception
{
try
{
Statement stmt = connection.createStatement();
stmt.execute(query);
stmt.close();
}
catch(Exception e)
{
throw new Exception((new StringBuilder()).append("Error executing query").append(e).toString());
}
}
/**
* Purpose: Must be called to tear down the connection.
*
*/
public void tearDown()
{
try
{
connection.close();
}
catch(Exception e) { }
connection = null;
query = "";
connectionName = "";
}
/**
* Purpose: Returns the query as a string.
* @return String
*/
public String getQuery()
{
return query;
}

}



To test your connection, add this coded to your setUser method in your UserAction class. This will test if you successfully connected to your database using my JDBCManager class.

Test your connection with following code:



JDBCManager managerJDBC = new JDBCManager();
managerJDBC.setJDBCName("jdbc/catalog");
managerJDBC.setUp();
managerJDBC.setQuery("select BookName from book");
System.out.println("Query: "+ managerJDBC.getQuery());
try
{
ResultSet rst = managerJDBC.getSet();
while(rst.next())
{
System.out.println("Book Name: "+ rst.getString("BookName"));
}
}
catch(Exception e)
{
System.out.println("Error with result set: "+e);
}
managerJDBC.tearDown();



Start Tomcat and go to your localhost and see if the bookname prints out in your console from your database. If it does, then you have successfully connected to the database.
Go To Hibernate Step 16C

Read more...

JDBC Connection to mySQL in Application Tomcat Step 16A

One way to connect to the database is by connecting within your application.

Make sure you have downloaded the mysql driver from: http://dev.mysql.com/downloads/connector/j/5.1.html


If you are connecting to another database, you need to make sure you download the driver for that particular database.

Put the driver in the tomcat/common/lib directory.


Add this method to your userAction class or the class you are using to connect.

public Connection getConnection(String username, String password,String database, String server) 
throws Exception { 
Connection connection = null; 
try { String driverName = ""; 
String url = "jdbc:mysql://"+ server +"/"+ database; driverName = "com.mysql.jdbc.Driver"; Class.forName(driverName).
newInstance(); // Create a connection to the database connection = DriverManager.getConnection(url, username, password); 
catch (Exception e) { // Could not connect to the database System.out.println("error getting access to database " e); return null; } 
return connection; 
}



You can put this code in the setUser method in our UserAction.java class to test your connection.


Connection connection=getConnection("UserBook","UserBook123","catalog","localhost");

String sql="select BookName from book";

PreparedStatement ps=null;
ps=connection.prepareStatement(sql);
ResultSet set=ps.executeQuery();

while(set!=null&&set.next()) {
System.out.println(set.getString("BookName")); }
connection.close();

This code gets your connection, queries your book table and displays all the booknames within your book table. You can check your console to see if the name of the books printed out to know that you accessed your database correctly.

Go To Hibernate Step 16C

Read more...

Wednesday, October 8, 2008

Pros and Cons JDBC and Hibernate Step 15

There are different ways of connecting to a database. I am going to talk about 3 of them.

1) You can connect using a JDBC connection within your Application

2) You can connect using a JDBC with your Application Server (Tomcat)

3) You can connect using Hibernate (Relational Mapping)


**************************************************
1) Opening a JDBC connection within your application is easier to do. However, you have to manage the amount of connections to the database within your application. You will have to open and close a connection each time you query the database. This usually is unnecessary overhead.
Go To JDBC Example Connection 1


2) Creating a connection within the Application Server can require more configuration. However, for optimum performance of database-intensive applications, the Application Server should manage the JDBC connection pool. Further, object pooling in the Application Server will also help to reduce the garbage collection load.
Go To JDBC Exampe Connection 2

3) Hibernate is much more complicated to use, but allows you to map the database to objects within your Application. If you are building a complicated system, then Hibernate might be the way to go. If your system only has a small amount of tables, then the JDBC connection might be the way to go. Hibernate also has some restrictions when it comes to querying the database. One example is using the relevance search in SQL Server. You are not able to do that in hibernate.

Go To Hibernate Example Connection 3


In my next posts, I will show you how to obtain database connections with those three options we just discussed.

Read more...

Saturday, October 4, 2008

Using Struts 1 tags in JSP with Java Bean Step 14

Now we are going to test out our our tags and attach a form to our Java Bean.

You need to replace your UserForm.java with this code:




package com.actionform;
import org.apache.struts.action.ActionForm;
public class UserForm extends ActionForm{
private static final long serialVersionUID = 123L;
private String firstName="";
private String lastName="";
private String middleName="";
private String email="";
public String getFirstName()
{
return firstName;
}
public void setFirstName(String name)
{
this.firstName=name;
}
public String getLastName()
{
return lastName;
}
public void setLastName(String name)
{
this.lastName=name;
}
public String getMiddleName()
{
return middleName;
}
public void setMiddleName(String name)
{
this.middleName=name;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email=email;
}
}



Add this method to UserAction.java



public ActionForward setUser(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
UserForm userForm=(UserForm)form;
System.out.println("User First Name Submitted: "+userForm.getFirstName());
System.out.println("User Last Name Submitted: "+userForm.getLastName());
System.out.println("User Middle Name Submitted: "+userForm.getMiddleName());
System.out.println("User Email Submitted: "+userForm.getEmail());
return mapping.findForward("success");
}


In your action form you added getter and setter methods to retrieve and set the users names and their email addresses. These are the same column names you have in the database.

You will have the user input data on the webpage, and when they submit the form, your action method will be called. The UserForm will pull the data to make sure the data was set correctly.

Now that we know your tiles work correctly, you can remove the test comments in your header.jsp, classiclayout.jsp and footer.jsp pages.

You need to add the rest of these tags to your include-taglibs.jspf page.



<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
<%@ taglib uri="http://struts.apache.org/tags-nested" prefix="nested" %>



These tags will allow you to use other tags that you will need in your jsp page.

Copy this code to your user.jsp page




<%@ include file="include-taglibs.jspf" %>
<body>
<html:form action="/UserAction.do?action=setUser" enctype="multipart/form-data" >
<table width="50%">
<tr>
<td width="25%">
First Name
</td>
<td width="25%">
<html:text property="firstName" size="20" maxlength="10" />
</td>
</tr>
<tr>
<td width="25%">
Last Name
</td>
<td width="25%">
<html:text property="lastName" size="20" maxlength="10" />
</td>
</tr>
<tr>
<td width="25%">
Middle Name
</td>
<td width="25%">
<html:text property="middleName" size="20" maxlength="10" />
</td>
</tr>
<tr>
<td width="25%">
Email
</td>
<td width="25%">
<html:text property="email" size="20" maxlength="20" />
</td>
</tr>
<tr>
<td width="50%">
<input type="Submit" value="Submit"/>
</td>
</tr>
</html:form>
</body>



At the top of the page you should include your import. Every page should include this import tag. You then have the struts html:form that informs what Struts Action will be called and what method will be called when the user submits the form. When the user submits this form, the UserAction.do will be called and it will call the setUser method that we added to the UserAction class. You will notice that you have the html:text tag in use too. The html:text tag attaches it to the UserForm class. The property is what method it is accessing. The first name is attached to the firstName method. The actual method is called FirstName, but you always start the property in lowercase, not uppercase. The rest of the page is regular html with a submit button at the bottom so the user can submit the form.

Build your new project and go to your localhost to see if your tags work correctly.

When you visit the project, you should see some input fields. Input some data, press submit, and verify that the data you inputted prints in your console. If it did, then your form works correctly. In my next post I will show you how to obtain a database connection to your mySQL database you created in my prior posts.

Go To Step 15

Read more...