Web Design Patterns at Work with Pagination

This example demonstrates the use of common web design patterns and gives a solution for pagination. I am using JSF as the MVC framework for this example.
I am using the authors database on mySQL which I have used in the previous examples. Refer the simple entity bean example on details of creation of the authors database and setting up of the mySQL datasource.
You need to set JBOSS_HOME and ANT_HOME before you can get on with this example.
You would also need to download the jsf jars listed under lib/jsfJars from the relevant website.

My work folder has the following structure:
build.xml

<build>
     <classes>
     <dist>
<webRoot>
     <web-INF>
         faces-config.xml
         web.xml
         html_basic.tld
         jsf_core.tld
<lib>
     <jsfJars>
         commons-beanutils.jar
         commons-collections.jar
         commons-digester.jar
         commons-logging.jar
         jsf-api.jar
         jsf-impl.jar
<src>
     <web>
         <mattiz>
              <pages>
                       author.jsp
                       authorAdded.jsp
                       authorPage.jsp
     <java>
         <com>
              <mattiz>
                       <beans>
                           AuthorDTO.java
                       <businessDelegates>
                           MattizDelegate.java
                       <dao>
                           MattizDAO.java
                       <exception>
                           MattizException.java
                       <web>
                           <managedBeans>
                                 AuthorBean.java

Let me list the web pages first:
author.jsp :


<%@page contentType="text/html"%>
<%@ taglib uri="/WEB-INF/html_basic.tld" prefix="h"%>
<%@ taglib uri="/WEB-INF/jsf_core.tld" prefix="f"%>
<html>
<head>
<title>author.jsp</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
	<f:view>
		<h:form>
			<h:panelGrid id="grid1" columns="2" border="0" width="100%">
				<h:outputText id="text1"
					style="color: #000099;font-family: Verdana, Arial, Helvetica, sans-serif;font-size: 10px;font-weight: bold;"
					value="Enter ISBN Code    :" />
				<h:inputText style="color: automatic; background: iceblue;"
					value="#{authorBean.isbnCode}" />
				<h:outputText id="text2"
					style="color: #000099;font-family: Verdana, Arial, Helvetica, sans-serif;font-size: 10px;font-weight: bold;"
					value="Enter Author Name:" />
				<h:inputText style="color: automatic; background: iceblue;"
					value="#{authorBean.author}" />
			</h:panelGrid>
			<h:panelGrid id="grid3" columns="2" border="0" width="100%">
				<h:commandButton value="Add" type="submit"
					action="#{authorBean.addAuthor}" />
			</h:panelGrid>
			<hr />
			<h:panelGrid id="grid5" columns="2" border="0" width="100%">
				<h:outputText id="text3"
					style="color: #000099;font-family: Verdana, Arial, Helvetica, sans-serif;font-size: 10px;font-weight: bold;"
					value="Paginate Author Details " />
			</h:panelGrid>
			<h:panelGrid id="grid6" columns="2" border="0" width="100%">
				<h:commandButton value="Paginate" type="submit"
					action="#{authorBean.displayAuthors}" />
			</h:panelGrid>
		</h:form>
	</f:view>
</body>
</html>

authorPage.jsp:

<%@page contentType="text/html"%>
<%@ taglib uri="/WEB-INF/html_basic.tld" prefix="h"%>
<%@ taglib uri="/WEB-INF/jsf_core.tld" prefix="f"%>
<html>
<head>
<title>authorPage.jsp</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
	<f:view>
		<h:form>
			<%
				if (request.getAttribute("count") != null) {
							int count = Integer.parseInt(request.getAttribute(
									"count").toString());
							int start = Integer.parseInt(request.getAttribute(
									"start").toString());
							int end = Integer.parseInt(request.getAttribute("end")
									.toString());
							int totRows = Integer.parseInt(request.getAttribute(
									"totRows").toString());
			%>
			<h:dataTable width="100%" border="0" id="values"
				value="#{authorBean.authorsList}" var="authorDTO"
				style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px;font-weight: bold; color: #000000">
				<h:column>
					<h:outputText value="#{authorDTO.isbnCode}"
						style="color: #000099;font-family: Verdana, Arial, Helvetica, sans-serif;font-size: 10px;font-weight: bold;" />
				</h:column>
				<h:column>
					<h:outputText value="#{authorDTO.author}"
						style="color: #000099;font-family: Verdana, Arial, Helvetica, sans-serif;font-size: 10px;font-weight: bold;" />
				</h:column>
			</h:dataTable>
			<%
				if (!(start == 1)) {
			%>
			<h:commandLink action="#{authorBean.displayAuthors}">
				<h:outputText value="PREV"
					style="color: #000099;font-family: Verdana, Arial, Helvetica, sans-serif;font-size: 10px;font-weight: bold;" />
				<f:param name="begin" value="#{start-10}" />
				<f:param name="finish" value="#{end-10}" />
				<f:param name="no" value="#{count}" />
				<f:param name="change" value="decr" />
			</h:commandLink>
			<%
				}
							if (!(count == totRows)) {
			%>
			<h:commandLink action="#{authorBean.displayAuthors}">
				<h:outputText value="NEXT"
					style="color: #000099;font-family: Verdana, Arial, Helvetica, sans-serif;font-size: 10px;font-weight: bold;" />
				<f:param name="begin" value="#{start+10}" />
				<f:param name="finish" value="#{end+10}" />
				<f:param name="no" value="#{count}" />
				<f:param name="change" value="incr" />
			</h:commandLink>
			<%
				}
						}
			%>
		</h:form>
	</f:view>
</body>
</html>

authorAdded.jsp :

<%@page contentType="text/html"%>
<%@ taglib uri="/WEB-INF/html_basic.tld" prefix="h"%>
<%@ taglib uri="/WEB-INF/jsf_core.tld" prefix="f"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>Author Added Page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
	<f:view>
Author added successfully to database
<h:form>
			<h:commandButton value="Back" type="submit" action="back" />
		</h:form>
	</f:view>
</body>
</html>

Next I list the java classes:

AuthorBean.java is the backing bean for all the jsp pages:

package com.mattiz.web.managedBeans;

import java.util.ArrayList;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.mattiz.Exception.MattizException;
import com.mattiz.beans.AuthorDTO;
import com.mattiz.businessDelegates.MattizDelegate;

public class AuthorBean {
	private String isbnCode;
	private String author;
	private HttpServletRequest request;
	private HttpSession session;
	ArrayList authorsList;

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public String getIsbnCode() {
		return isbnCode;
	}

	public void setIsbnCode(String isbnCode) {
		this.isbnCode = isbnCode;
	}

	public String addAuthor() {
		AuthorDTO authorDTO = new AuthorDTO(getIsbnCode());
		authorDTO.setAuthor(getAuthor());
		MattizDelegate mattizDelegate = new MattizDelegate();
		try {
			mattizDelegate.addAuthor(authorDTO);
		} catch (MattizException me) {

		}
		return "authorAdded";
	}

	public String displayAuthors() {
		FacesContext context = FacesContext.getCurrentInstance();
		request = (HttpServletRequest) context.getExternalContext()
				.getRequest();
		session = request.getSession();
		MattizDelegate mattizDelegate = new MattizDelegate();
		try {
			int start = 1;
			int end = 10;
			if (request.getParameter("begin") != null) {
				start = Integer.parseInt(request.getParameter("begin"));
			}
			if (request.getParameter("finish") != null) {
				end = Integer.parseInt(request.getParameter("finish"));
			}
			authorsList = mattizDelegate.getAuthors(start, end);
			int count = 0;
			String change = "incr";
			if (request.getParameter("no") != null) {
				count = Integer.parseInt(request.getParameter("no"));
			}
			int totalRows = mattizDelegate.getNumberOfRows();
			if (request.getParameter("change") != null) {
				change = request.getParameter("change").toString();
			}
			if (change.equals("incr")) {
				request.setAttribute("count",
						new Integer(count + authorsList.size()));
			} else if (change.equals("decr")) {
				request.setAttribute("count", new Integer(end));
			}
			request.setAttribute("start", new Integer(start));
			request.setAttribute("end", new Integer(end));
			request.setAttribute("totRows", new Integer(totalRows));
		} catch (MattizException me) {

		}
		return "paginateAuthors";
	}

	public ArrayList getAuthorsList() {
		return authorsList;
	}

	public void setAuthorsList(ArrayList authorsList) {
		this.authorsList = authorsList;
	}
}

MattizDelegate.java is the business delegate class:

package com.mattiz.businessDelegates;

import java.util.ArrayList;
import com.mattiz.Exception.MattizException;
import com.mattiz.beans.AuthorDTO;
import com.mattiz.dao.MattizDAO;

public class MattizDelegate {
	MattizDAO mattizDAO;

	public MattizDelegate() {
		mattizDAO = new MattizDAO();
	}

	public void addAuthor(AuthorDTO author) throws MattizException {
		mattizDAO.addAuthor(author);
	}

	public ArrayList getAuthors(int start, int end) throws MattizException {
		ArrayList authorArray = mattizDAO.getAuthors(start, end);
		return authorArray;
	}

	public int getNumberOfRows() throws MattizException {
		int rowCount = mattizDAO.getNumberOfRows();
		return rowCount;
	}
}

MattizDAO.java is the Data Access Object class. Note helper method closeStatements(ResultSet rs, PreparedStatement ps, Connection conn) which adds elegance to how connections are created, statements initialized and later disposed off.

package com.mattiz.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import com.mattiz.Exception.MattizException;
import com.mattiz.beans.AuthorDTO;

public class MattizDAO {
	private static DataSource ds;
	public static final String DATASOURCE_LOOKUP_NAME = "java:dbpool";

	public MattizDAO() {
		try {
			InitialContext ctx = null;
			ctx = new InitialContext();
			ds = (DataSource) ctx.lookup(DATASOURCE_LOOKUP_NAME);
		} catch (javax.naming.NamingException jnx) {
			// log an error declaring connection could not be created
			// object MattizDAO could not be initialized
		}
	}

	public void addAuthor(AuthorDTO author) throws MattizException {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = ds.getConnection();
			String qry = "insert into authors values(?,?);";
			ps = conn.prepareStatement(qry);
			ps.setString(1, author.getIsbnCode());
			ps.setString(2, author.getAuthor());
			// other examples of setters for prepared statement below:
			// ps.setInt(3, 0);
			// ps.setDate(4, new java.sql.Date(1 - 1 - 2007));
			// ps.setTime(5, new java.sql.Time(1 - 1 - 2007));
			// ps.setDouble(6, 1);
			ps.execute();// in case this is an insert/ update
			// PreparedStatement ps, ResultSet rs, Connection conn can be reused
			// with new values for another query
		} catch (SQLException e) {
			throw new MattizException();
		} finally {
			closeStatements(rs, ps, conn);
		}
	}

	public ArrayList getAuthors(int start, int end) throws MattizException {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		ArrayList authorsList;
		try {
			conn = ds.getConnection();
			String qry = "select * from authors;";
			ps = conn.prepareStatement(qry);
			rs = ps.executeQuery();// in case this is a select
			authorsList = new ArrayList();
			int counter = 0;
			while (rs.next()) {
				counter++;// loop till counter>=start
				if (counter >= start && counter <= end) {
					AuthorDTO authorDTO = new AuthorDTO(
							rs.getString("isbn_code"));
					authorDTO.setAuthor(rs.getString("author"));
					authorsList.add(authorDTO);
				} else if (counter > end) {// break out of loop when
				// counter>end
					break;
				}
			}
			// PreparedStatement ps, ResultSet rs, Connection conn can be reused
			// for another query
		} catch (SQLException e) {
			throw new MattizException();
		} finally {
			closeStatements(rs, ps, conn);
		}
		return authorsList;
	}

	public int getNumberOfRows() throws MattizException {
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		int rowCount = 0;
		try {
			conn = ds.getConnection();
			String qry = "select count(*) from authors;";
			ps = conn.prepareStatement(qry);
			rs = ps.executeQuery();
			if (rs.next()) {
				rowCount = rs.getInt(1);
			}
		} catch (SQLException e) {
			throw new MattizException();
		} finally {
			closeStatements(rs, ps, conn);
		}
		return rowCount;
	}

	private void closeStatements(ResultSet rs, PreparedStatement ps,
			Connection conn) throws MattizException {
		if (rs != null) {
			try {
				rs.close();
			} catch (Exception e) {
				throw new MattizException();
			}
			rs = null;
		}
		if (ps != null) {
			try {
				ps.close();
			} catch (Exception e) {
				throw new MattizException();
			}
			ps = null;
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (Exception e) {
				throw new MattizException();
			}
			conn = null;
		}
	}
}

AuthorDTO.java is the Data Transfer Object (Value Object):

package com.mattiz.beans;

public class AuthorDTO {
	private String isbnCode;
	private String author;

	public AuthorDTO(String isbnCode) {
		this.isbnCode = isbnCode;
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public String getIsbnCode() {
		return isbnCode;
	}
}

I use one exception class in the example and MattizException.java :

package com.mattiz.Exception;

public class MattizException extends Exception {
	public MattizException() {
		super();
	}

	public MattizException(String msg) {
		super(msg);
	}
}

web.xml configure the Faces Servlet which is the controller for the JSF framework, and the location of the faces-config.xml file which is the configuration file for JSF:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	version="2.4"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<context-param>
		<param-name>javax.faces.CONFIG_FILES</param-name>
		<param-value>/WEB-INF/faces-config.xml</param-value>
	</context-param>
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>0</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.faces</url-pattern>
	</servlet-mapping>
</web-app>

faces-config.xml defines the navigation rules for the JSF framework and defines the managed beans (backing beans) for the jsp pages:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
	<navigation-rule>
		<navigation-case>
			<from-outcome>authorAdded</from-outcome>
			<to-view-id>/pages/authorAdded.jsp</to-view-id>
		</navigation-case>
	</navigation-rule>
	<navigation-rule>
		<navigation-case>
			<from-outcome>paginateAuthors</from-outcome>
			<to-view-id>/pages/authorPage</to-view-id>
		</navigation-case>
	</navigation-rule>
	<navigation-rule>
		<navigation-case>
			<from-outcome>back</from-outcome>
			<to-view-id>/pages/author.jsp</to-view-id>
		</navigation-case>
	</navigation-rule>
	<managed-bean>
		<description>JSF Backing Bean for adding/paginating author
		</description>
		<managed-bean-name>authorBean</managed-bean-name>
		<managed-bean-class>com.mattiz.web.managedBeans.AuthorBean</managed-bean-class>
		<managed-bean-scope>request</managed-bean-scope>
	</managed-bean>
</faces-config>

build.xml automates the build process. The compiled classes are placed under build/classes folder of root, later zipped as a jar, the jar included within lib of the war (the jar and war files are placed temporarily in build/dist). The war file is finally deployed to jboss deploy folder.

Run build.xml from the command prompt with the following command:
ant install

<?xml version="1.0" encoding="UTF-8"?>
<project name="Mattiz" default="install" basedir=".">
	<property environment="env" />
	<property name="build.dir" location="build" />
	<property name="build.classes.dir" location="${build.dir}/classes" />
	<property name="build.dist.dir" location="${build.dir}/dist" />
	<property name="java.src.dir" location="src/java" />
	<property name="web.src.dir" location="src/web/mattiz" />
	<property name="JBOSS_HOME" location="${env.JBOSS_HOME}" />
	<property name="install.jboss.deploy.dir" location="${JBOSS_HOME}/server/default/deploy" />
	<property name="jsfJars.dir" location="lib/jsfJars" />
	<path id="build.path">
		<pathelement location="${JBOSS_HOME}/server/default/lib/jboss-j2ee.jar" />
		<pathelement location="${JBOSS_HOME}/client/javax.servlet.jar" />
		<pathelement location="${jsfJars.dir}/jsf-api.jar" />
	</path>
	<target name="clean">
		<delete file="${build.dist.dir}/mattiz.jar" />
		<delete file="${build.dist.dir}/mattiz.war" />
		<delete file="${install.jboss.deploy.dir}/mattiz.war" />
		<delete dir="${build.classes.dir}" />
	</target>
	<target name="init">
		<mkdir dir="${build.dir}" />
		<mkdir dir="${build.classes.dir}" />
		<mkdir dir="${build.dist.dir}" />
	</target>
	<target name="compile" depends="init">
		<javac srcdir="${java.src.dir}" destdir="${build.classes.dir}"
			debug="on" deprecation="on" classpathref="build.path" optimize="off" />
	</target>
	<target name="jar" depends="compile">
		<jar destfile="${build.dist.dir}/mattiz.jar">
			<fileset dir="${build.classes.dir}" includes="**/*" excludes="**/*.java" />
		</jar>
		<copy todir="${build.classes.dir}">
			<fileset dir="${java.src.dir}" />
		</copy>
		<war destfile="${build.dist.dir}/mattiz.war" webxml="WebRoot/WEB-INF/web.xml">
			<webinf dir="WebRoot/WEB-INF" />
			<lib dir="${jsfJars.dir}" />
			<lib dir="${build.dist.dir}" includes="mattiz.jar" />
			<zipfileset dir="${web.src.dir}/pages" prefix="pages" />
		</war>
	</target>
	<target name="install" depends="jar">
		<copy overwrite="${FORCE}" todir="${install.jboss.deploy.dir}">
			<fileset dir="${build.dist.dir}">
				<include name="mattiz.war" />
			</fileset>
		</copy>
	</target>
</project>

The war file created has the following structure:

<meta-INF>
<pages>
     author.jsp
     authorAdded.jsp
     authorPage.jsp
<web-INF>
     web.xml
     faces-config.xml
     html_basic.tld
     jsf_core.tld
     <lib>
          commnons-collections.jar
          commons-beanutils.jar
          commons-digester.jar
          jsf-impl.jar
          jsf-api.jar
          {mattiz.jar}
               <meta-INF>
               <com>
                   <mattiz>
                          <beans>
                               AuthorDTO.class
                          <businessDelegates>
                               MattizDelegate.class
                          <dao>
                               MattizDAO.class
                          <exception>
                               MattizException.class
                          <web>
                               <managedBeans>
                                         AuthorBean.class

Start the application with the following URL:

http://localhost:8080/mattiz/pages/author.faces

You are provided with an option to add entries to the database, so that you have enough entries in the database to see pagination work.

Putting it all together:

The Faces Servlet configured in web.xml acts as the Front Controller. It is not manually coded as it is part of the JSF MVC architecture (implied). The request from the client reaches the Front Controller, usually implemented as a servlet. It may use JavaBeans to access the information from the database that is required to authenticate the request. Then, depending on the state of the client’s session, the Front Controller determines to which other worker objects the request will be forwarded for processing. Finally, after the request has been processed, the last worker servlet will forward the request to one of the JSP pages for presenting the data to the client.
During the processing of the request, multiple servlets or JSP pages may be involved, each one optionally creating and updating JavaBeans. In this case, the beans act as the model, the servlets are the controller, and the JSP pages are the view. The beans work closely with the Business Delegate objects to send and receive business data in the form of Value Objects to the business tier, where these data objects are processed and
transactions are performed.
All business objects then make use of Data Access Objects, to fetch and update data from the data store. The DAO shields the business objects from the management chores of the data stores.
Winding it up, in this example we have given examples of four design patterns — Value Object, MVC, Data Access Object, and Business Delegate—and the Front Controller.

Code can be downloaded here

Jboss, Oracle and Entity Beans

I have modified the Simple Entity Bean Example (Nov. 2005 – updated) which used mySQL, to use Oracle instead. I have reused most of the stuff and also used the same directory structure.
I am using jboss-4.0.3SP1, SQL Plus as the Oracle client and Oracle8i, which may happen to be a pretty old version, but still compatible with newer versions of Oracle.
Here are the changes I made to get the Simple Entity Example up and going on Oracle in place of mySQL:
For creating the entity bean, we need to first create a database table. I am using the default Oracle database with username/password: scott/tiger. The driver used is classes12.zip which is still available on the Oracle site (though you may have to register yourself on the site before you proceed).The entity used in this example uses a table called AUTHORS in the default database which has two fields ISBN_CODE and AUTHOR. Here are the scripts to create the table. Run them by logging into SQL Plus with username/ password/hoststring, scott/tiger/mattiz where mattiz is the Oracle sid entered while creating the database.

CREATE TABLE authors (ISBN_CODE varchar2(10) default '0',AUTHOR varchar2(30) default NULL,PRIMARY KEY (ISBN_CODE)) ;

instead of this mySQL query

CREATE TABLE authors (ISBN_CODE varchar(10) NOT NULL default '0',AUTHOR varchar(30) default NULL,PRIMARY KEY (ISBN_CODE)) ;

Note the use of single quote and varchar2 datatype in the Oracle query. Also when a primary key (ISBN_CODE here) is speciifed, you don’t specify NOT NULL, in Oracle.
So other variations of the script would be as follows, though we don’t use them in our example:

CREATE TABLE authors2 (ISBN_CODE varchar2(10) default '0',AUTHOR varchar2(30) not null,PRIMARY KEY (ISBN_CODE)) ;
CREATE TABLE authors3 (ISBN_CODE varchar2(10) default '0',AUTHOR varchar2(30) default 'ANON',PRIMARY KEY (ISBN_CODE)) ;

Also an insert in Oracle for the first query would look like:

insert into authors values('1e','manik');

or

insert into authors (ISBN_CODE, AUTHOR )values('2e', 'garh');

Use of double quotes though permissible in mySQL will not work in SQL client. Anyway using double quotes in SQL scripts is a bad practice.

Name              Null?              Type
----------------------------------------- -------- ----------------------------
ISBN_CODE         NOT NULL           VARCHAR2(10)
AUTHOR                               VARCHAR2(30)

1. Copy the Oracle driver classes12.zip to server/default/lib.
2. Add this entry to login-config.xml in jboss’s conf folder:


<application-policy name="oracleDbRealm">
	<authentication>
		<login-module
			code="org.jboss.resource.security.ConfiguredIdentityLoginModule"
			flag="required">
			<module-option name="principal">admin</module-option>
			<module-option name="userName">scott</module-option>
			<module-option name="password">tiger</module-option>
			<module-option name="managedConnectionFactoryName">
				jboss.jca:service=LocalTxCM,name=oracledbpool
</module-option>
		</login-module>
	</authentication>
</application-policy>


3. Create oracle-ds.xml as follows:


<?xml version="1.0" encoding="UTF-8"?>
<datasources>
	<local-tx-datasource>
		<jndi-name>oracledbpool</jndi-name>
		<connection-url>jdbc:oracle:thin:@localhost:1521:mattiz
		</connection-url>
		<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
		<user-name>scott</user-name>
		<password>tiger</password>
		<security-domain>oracleDbRealm</security-domain>
		<metadata>
			<type-mapping>Oracle</type-mapping>
		</metadata>
	</local-tx-datasource>
</datasources>

Place oracle-ds.xml under server/default/deploy.
1521 is the default oracle port. Also note that “mattiz” used in the connection url is the Oracle sid.
4. Modify jbosscmp-jdbc.xml so that it looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jbosscmp-jdbc PUBLIC "-//JBoss//DTD JBOSSCMP-JDBC 4.0//EN" "http://www.jboss.org/j2ee/dtd/jbosscmp-jdbc_4_0.dtd">
<jbosscmp-jdbc>
	<defaults>
		<datasource>java:/oracledbpool</datasource>
		<datasource-mapping>Oracle8</datasource-mapping>
	</defaults>
	<enterprise-beans>
		<entity>
			<ejb-name>AuthorsBean</ejb-name>
			<create-table>false</create-table>
			<table-name>Authors</table-name>
			<cmp-field>
				<field-name>isbnCode</field-name>
				<column-name>ISBN_CODE</column-name>
			</cmp-field>
			<cmp-field>
				<field-name>authorName</field-name>
				<column-name>AUTHOR</column-name>
			</cmp-field>
		</entity>
	</enterprise-beans>
</jbosscmp-jdbc>

5. Modify standard-jbosscmp-jdbc.xml under server/default/conf to change the default datasource

<datasource>java:/oracledbpool></datasource>

Now you are ready to go.
Do a build, fire up jboss and start the application just as you did in the simple entity bean example.