Additional Code for this article - war file ~3MB

Listing 1: Struts Configuration File

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
 "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">

<struts-config>
	<!-- Data Sources -->
<data-sources>
</data-sources>

	<!-- Form Beans -->
	<form-beans>
	</form-beans>

	<!-- Global Exceptions -->
	<global-exceptions>
	</global-exceptions>

	<!-- Global Forwards -->
	<global-forwards>
	</global-forwards>

	<!-- Action Mappings -->
	<action-mappings>
	</action-mappings>
</struts-config>


Listing 2: Enabling Struts Support in web.xml

<servlet>
		<servlet-name>action</servlet-name>
		<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
		<init-param>
			<param-name>config</param-name>
			<param-value>/WEB-INF/struts-config.xml</param-value>
		</init-param>
		<init-param>
			<param-name>debug</param-name>
			<param-value>2</param-value>
		</init-param>
		<init-param>
			<param-name>detail</param-name>
			<param-value>2</param-value>
		</init-param>
		<init-param>
			<param-name>validate</param-name>
			<param-value>true</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>action</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>

Listing 3: Abstract Action Class

package actions;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

// This abstract class overrides Struts action class execute method and provides abstract 
// performAction method to be overwritten by sub-classes. This helps us isolate some
// common error processing into one place, rather than having it several places in the 
// sub-classes.

public abstract class AbstractAction extends Action {

		public ActionForward execute(
			ActionMapping mapping,
			ActionForm form,
			HttpServletRequest request,
			HttpServletResponse response)
			throws Exception {

			// Define action errors and forward
			ActionErrors errors = new ActionErrors();
			ActionForward forward = new ActionForward();
			
			try {
			          forward = performAction(mapping, form, request, response);
			} catch (Exception e) {
				// Report the error using the appropriate name and ID.
				errors.add("name", new ActionError("id"));
			}

			// If a message is required, save the specified key(s)
			// into the request for use by the <struts:errors> tag.
			

Listing 4: Contents of new performAction method.

			if (!errors.isEmpty()) {
				saveErrors(request, errors);
				// Forward control to the appropriate 'failure' URI 
				forward = mapping.findForward("failure");
			} else {
				// Forward control to the appropriate 'success' URI 
				if (forward == null) {
					forward = mapping.findForward("success");
				}
			}

			// Finish with
			return (forward);

		}
		
		/**
		 * Perform appropriate actions as defined by the business logic
		 * 
		 * @param mapping
		 * @param form
		 * @param request
		 * @param response
		 * @return
		 * @throws Exception
		 */
		public abstract ActionForward performAction (
				ActionMapping mapping,
				ActionForm form,
				HttpServletRequest request,
				HttpServletResponse response)
				throws Exception;
}



// create customer - get parameters first
		String first_name = request.getParameter("first_name");
		String last_name = request.getParameter("last_name");
		String address = request.getParameter("address");
		int cust_id = Math.abs((int)System.currentTimeMillis());
		
		// create new customer object
		Customer c = new Customer();
		c.setId(cust_id);
		c.setFirstName(first_name);
		c.setLastName(last_name);
		c.setAddress(address);
		
		// construct and execute database command
		DatabaseCommand command = new CreateCustomer(c);
		int rows = (Integer)CommandExecutor.getInstance().executeDatabaseCommand(command);
		
		return mapping.findForward("customer_created");


Listing 5: Action Mapping for the Create Customer Action

	<action path="/CreateCustomer" type="actions.CreateCustomerAction">
			<forward name="customer_created" path="/customer_created.jsp">
			</forward>
			<forward name="failure" path="/failure.jsp">
			</forward>
		</action>

Listing 6: Failure JSP File

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Failure has occurred</title>
</head>
<body>
<B>Errors occurred</B>
<html:errors/>
</body>
</html>

Listing 7: The Hibernate Configuration File

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.datasource">java:comp/env/jdbc/TestDB</property>
<property name="show_sql">true</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Mapping files -->
<mapping resource="hibernate.mapping.xml"/>
</session-factory>
</hibernate-configuration>

Listing 8: The Hibernate mapping file

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping> 
  <class name="domain.Customer" table="CUSTOMER" lazy="false"> 
    <id name="id" column="ID"/> 
    <property name="firstName" column="FIRST_NAME"/> 
    <property name="lastName" column="LAST_NAME"/> 
    <property name="address" column="ADDRESS"/> 
  </class> 
  <class name="domain.Order" table="ORDERS" lazy="false"> 
    <id name="id" column="ID"/> 
    <property name="custId" column="CUST_ID"/> 
    <property name="datePlaced" column="DATE_PLACED"/> 
    <property name="orderAmount" column="AMOUNT"/> 
  </class> 
</hibernate-mapping>

Listing 9: New access method for the session factory

// get hibernate session factory
public SessionFactory getSessionFactory() {
	if (sessionFactory == null) {
		sessionFactory = new Configuration().configure().buildSessionFactory();
	}
	return sessionFactory;
}

Listing 10: Execute the Hibernate Command

// execute a particular hibernate command
public Object executeHibernateCommand(DatabaseCommand c) throws Exception {
	Session session = null;
	try {
		session = getSessionFactory().openSession();
		Object o = c.executeHibernateOperation(session);
		return o;
	} catch (SQLException e) {
		throw e;
	} finally {
		if (session != null) {
			session.flush();
			session.close();
		}
	}
}

Listing 11: The executeDatabaseOperation() Method of the CreateCustomer Class

public Object executeDatabaseOperation(Connection conn) throws SQLException {
		PreparedStatement sta = conn.prepareStatement
		("INSERT INTO CUSTOMER (ID, FIRST_NAME, LAST_NAME, ADDRESS) VALUES (?, ?, ?, ?)");
		sta.setInt(1, cust.getId());
		sta.setString(2, cust.getFirstName());
		sta.setString(3, cust.getLastName());
		sta.setString(4, cust.getAddress());
		int rows_updated = sta.executeUpdate();
		sta.close();
		return new Integer(rows_updated);
	}

Listing 12: The executeHibernateOperation() method for CreateCustomer Class

/**
 *  Execute Hibernate operation
 */
public Object executeHibernateOperation(Session session) throws SQLException {
	session.save(cust);
	session.flush();
	return 1;
}

Listing 13: The executeDatabaseOperation() method for the ListCustomers Class

public Object executeDatabaseOperation(Connection conn) throws SQLException {
	// List customers in the database
		
		ArrayList<Customer> list = new ArrayList<Customer>();
		Statement sta = conn.createStatement();
		ResultSet rs = sta.executeQuery("SELECT ID, FIRST_NAME, LAST_NAME, ADDRESS FROM CUSTOMER");
		while(rs.next()) {
			Customer cust = new Customer();
			cust.setId(rs.getInt(1));
			cust.setFirstName(rs.getString(2));
			cust.setLastName(rs.getString(3));
			cust.setAddress(rs.getString(4));
			list.add(cust);
		}
		rs.close();
		sta.close();
		return list;
}

Listing 14: The executeHibernateOperation() method for the ListCustomers Class

/**
 *  Execute Hibernate select operation
 */
public Object executeHibernateOperation(Session session) throws SQLException {
	Query q = session.createQuery("from customer in class domain.Customer");
	Iterator iter = q.iterate();
	ArrayList<Customer> list = new ArrayList<Customer>();
	while(iter.hasNext()) {
		Customer cust = (Customer)iter.next();
		list.add(cust);
	}
	return list;
}

Listing 15: The executeHibernateOperation() Method for the ListCustomerOrders Class

/**
 *  Execute Hibernate query operation
 */
public Object executeHibernateOperation(Session session) throws SQLException {
	Query q = session.createQuery("from order in class domain.Order where order.custId = '" + this.cust_id + "'");
	Iterator iter = q.iterate();
	ArrayList<Order> list = new ArrayList<Order>();
	while(iter.hasNext()) {
		Order order = (Order)iter.next();
		list.add(order);
	}
	return list;
}

Additional Code for this article - war file ~3MB