Using mysql-ds.xml and applicationContext-data with the Hibernate Example

In the previous Hibernate example with mySQL, the datasource was configured in spring-servlet.xml http://cuppajavamattiz.com/2007/09/15/a-simple-spring-hibernate-example/ In this example we do away with spring-servlet.xml and instead use a combination of mysql-ds.xml and applicationContext-data.xml to configure the datasource.
We also add ehcache-1.2.4.jar to lib/third-party from spring-framework-2.0.6-with-dependencies/lib/ehcache in spring-framework-2.0.6-with-dependencies.zip that comes with the spring distribution.

web.xml is modified as follows:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app>
	<!-- Spring listener -->
		<listener>
			<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>
	<!-- Faces Servlet -->
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<!-- Faces Servlet Mapping -->
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.jsf</url-pattern>
	</servlet-mapping>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/applicationContext*.xml</param-value>
	</context-param>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

mysql-ds.xml is put in server/default/deploy and has the following source:

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
	<local-tx-datasource>
		<jndi-name>dbpool</jndi-name>
		<connection-url>jdbc:mysql://localhost:3306/AUTHORS</connection-url>
		<driver-class>com.mysql.jdbc.Driver</driver-class>
		<user-name>admin</user-name>
		<password>admin</password>
		<metadata>
			<type-mapping>mySQL</type-mapping>
		</metadata>
	</local-tx-datasource>
</datasources>

applicationContext-data.xml is introduced in conf folder of work and has following source:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<!-- Spring configuration file with data services layer configuration. -->
<beans>
	<bean id="dataSourceMySQL" class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiName" value="java:/dbpool" />
	</bean>
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="mappingJarLocations">
			<value>WEB-INF/lib/mattiz.jar</value>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
				<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
				<prop key="hibernate.jdbc.use_get_generated_keys">true</prop>
				<prop key="hibernate.order_updates">true</prop>
				<prop key="hibernate.cache.use_query_cache">true</prop>
			</props>
		</property>
		<property name="dataSource">
			<ref local="dataSourceMySQL" />
		</property>
	</bean>
	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory">
			<ref local="sessionFactory" />
		</property>
		<property name="jdbcExceptionTranslator">
			<ref local="jdbcExceptionTranslator" />
		</property>
	</bean>
	<bean id="jdbcExceptionTranslator"
		class="org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator">
		<property name="dataSource">
			<ref local="dataSourceMySQL" />
		</property>
	</bean>
</beans>

Note:
You can configure JNDI instead of datasource in spring configuration file using “org.springframework.jndi.JndiObjectFactoryBean”.

<bean id="dataSourceMySQL" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:/dbpool" />
</bean>


Note:
Caching is widely used for optimizing database applications. Hibernate uses two different caches for objects: first-level cache and second-level cache.
First-level cache is associated with the Session object, while second-level cache is associated with the Session Factory object. By default, Hibernate uses first-level cache on a per-transaction basis. Hibernate uses this cache mainly to reduce the number of SQL queries it needs to generate within a given transaction. For example, if an object is modified several times within the same transaction, Hibernate will generate only one SQL UPDATE statement at the end of the transaction, containing all the modifications.
To reduce database traffic, second-level cache keeps loaded objects at the Session Factory level between transactions. These objects are available to the whole application, not just to the user running the query. This way, each time a query returns an object that is already loaded in the cache, one or more database transactions potentially are avoided. In addition, you can use a query-level cache if you need to cache actual query results, rather than just persistent objects. The query cache should always be used in conjunction with the second-level cache. One of the open source cache implementation that Hibernate supports out-of-the-box is EhCache.

EHCache is a fast, lightweight, and easy-to-use in-process cache. It supports read-only and read/write caching, and memory- and disk-based caching. However, it does not support clustering.

To activate second-level caching, you need to define the hibernate.cache.provider_class property in the hibernate.cfg.xml file as follows:

<hibernate-configuration>
<session-factory>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EHCacheProvider</property>
</session-factory>
</hibernate-configuration>

By default, the second-level cache is activated and uses the EHCache provider. To use the query cache you must first enable it by setting the property hibernate.cache.use_query_cache to true in hibernate.properties.

applicationContext-service.xml replaces applicationContext.xml in the original application while the source remains unchanged.

Rest of the files is reused and no other modification is made.

Modifying the above example to use Oracle database

Instead of mysql-ds.xml we place oracle-ds.xml in server/default/deploy which has the following source:

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
	<local-tx-datasource>
		<jndi-name>oradbpool</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>
		<metadata>
			<type-mapping>Oracle</type-mapping>
		</metadata>
	</local-tx-datasource>
</datasources>

applicationContext-data.xml in conf of work folder is modified thus:;

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<!-- Spring configuration file with data services layer configuration. -->
<beans>
	<bean id="dataSourceOra" class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiName" value="java:/oradbpool" />
	</bean>
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="mappingJarLocations">
			<value>WEB-INF/lib/mattiz.jar</value>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
				<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
				<prop key="hibernate.jdbc.use_get_generated_keys">true</prop>
				<prop key="hibernate.order_updates">true</prop>
				<prop key="hibernate.cache.use_query_cache">true</prop>
			</props>
		</property>
		<property name="dataSource">
			<ref local="dataSourceOra" />
		</property>
	</bean>
	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory">
			<ref local="sessionFactory" />
		</property>
		<property name="jdbcExceptionTranslator">
			<ref local="jdbcExceptionTranslator" />
		</property>
	</bean>
	<bean id="jdbcExceptionTranslator"
		class="org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator">
		<property name="dataSource">
			<ref local="dataSourceOra" />
		</property>
	</bean>
</beans>

Note that both oracle-ds.xml and mysql-ds.xml can co-exist in server/default/deploy

Download source code here Spring_Hibernate_with_app_context_data

Get the Oracle version here Oracle_Hibernate_version

Running the Hibernate Application with Oracle

I am using the default database that comes with the Oracle implementation.
The username/password for this database is scott/tiger and the SID I have presumed is mattiz (This is set during Oracle installation.).
I changed only one file in the application described in the previous blog, that is, spring-servlet.xml. http://cuppajavamattiz.com/2007/09/15/a-simple-spring-hibernate-example/ I also copied the oracle driver ojdbc14.zip to server/default/lib. (The driver can be got from the Oracle website.)
Change is only to one configuration file: spring-servlet.xml.
Here is the source for the modified spring-servlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!-- - Application context definition for "springapp" DispatcherServlet. -->
<beans>
	<!-- Business Layer beans definition -->
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass">
			<value>org.springframework.web.servlet.view.JstlView</value>
		</property>
	</bean>
	<!-- Oracle DataSource Definition -->
	<bean id="dataSourceOracle" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:mattiz" />
		<property name="username" value="scott" />
		<property name="password" value="tiger" />
	</bean>
	<!-- Hibernate SessionFactory Definition -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="mappingJarLocations">
			<value>WEB-INF/lib/mattiz.jar</value>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.OracleDialect
				</prop>
				<prop key="hibernate.show_sql">true</prop>
			</props>
		</property>
		<property name="dataSource">
			<ref local="dataSourceOracle" />
		</property>
	</bean>
	<!-- Hibernate Template Defintion -->
	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory">
			<ref local="sessionFactory" />
		</property>
		<property name="cacheQueries" value="false" />
		<property name="jdbcExceptionTranslator">
			<ref local="jdbcExceptionTranslator" />
		</property>
	</bean>
	<bean id="jdbcExceptionTranslator"
		class="org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator">
		<property name="dataSource">
			<ref local="dataSourceOracle" />
		</property>
	</bean>
</beans>

Get source code here Hibernate_with_Oracle

A Simple Spring-Hibernate Example

The notes on the simple session bean and entity bean examples on this blog use EJB1.1. Sadly, now it seems that the latest versions of JBoss no longer support this version of EJB. So you would not be able to run the Entity Bean and Session Bean examples posted earlier on this blog with the latest versions of JBoss.
Also there seems to be an increasing trend to use ORM (Object Relational Model) persistence frameworks such as Hibernate.
I describe below a simple hibernate example. I am using jboss-4.2.1.GA and spring-framework-2.0.6-with-dependencies.zip as the integrated Spring-Hibernate package.
The version of Ant I am using is 1.7.0

I am using the same database used with the earlier examples. For convenience I am repeating the scripts you need to run after a fresh mySQL installation:

--user=root mysql
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'admin' WITH GRANT OPTION;
create database AUTHORS;
use AUTHORS;
CREATE TABLE authors (ISBN_CODE varchar(10) NOT NULL default '0',AUTHOR varchar(30) default NULL,PRIMARY KEY  (ISBN_CODE)) ;
insert into authors (ISBN_CODE,AUTHOR )values("1e","matty");

The username and password for mySQL is assumed to be “admin” and “admin”.

The mySQL datasource is configured in spring-servlet.xml and hence mysql-ds.xml is not required to be deployed in server/default/deploy:

Copy mysql-connector-java-3.1.8-bin.jar mySQL driver to jboss’s lib folder

Add the following to log4j.xml to server/default/conf folder


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
	debug="false">

	<!-- ================================= -->
	<!-- Preserve messages in a local file -->
	<!-- ================================= -->

	<appender name="FILE" class="org.apache.log4j.RollingFileAppender">
		<param name="File" value="${jboss.server.home.dir}/log/mattiz.log" />
		<param name="Append" value="true" />
		<param name="MaxFileSize" value="100MB" />
		<param name="MaxBackupIndex" value="3" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%d %-5p [%c] %m%n" />
		</layout>
	</appender>

	<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
		<param name="Target" value="System.out" />
		<param name="Threshold" value="INFO" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%d{ISO8601} %-5p [%c{1}] %m%n" />
		</layout>
	</appender>

	<category name="javax.faces">
		<priority value="ERROR" />
		<appender-ref ref="FILE" />
	</category>

	<category name="org.jboss.axis">
		<priority value="ERROR" />
		<appender-ref ref="FILE" />
	</category>

	<category name="org.jboss.management">
		<priority value="ERROR" />
		<appender-ref ref="FILE" />
	</category>

	<category name="org.apache">
		<priority value="ERROR" />
		<appender-ref ref="FILE" />
	</category>

	<category name="org.hibernate">
		<priority value="ERROR" />
		<appender-ref ref="FILE" />
	</category>
	<category name="org.springframework">
		<priority value="ERROR" />
		<appender-ref ref="FILE" />
	</category>
	<category name="org.jboss">
		<priority value="INFO" />
		<appender-ref ref="FILE" />
	</category>
	<category name="com.mattiz">
		<priority value="DEBUG" />
	</category>
	<root>
		<appender-ref ref="CONSOLE" />
		<appender-ref ref="FILE" />
	</root>
	<!--error -> warn -> info -> debug -->
</log4j:configuration>

My work folder for Ant looks like this:
simple_spring
Web layer configuration files:

web.xml looks like this:


<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app>

	<!-- Spring listener -->
	<listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
</listener-class>
	</listener>

	<!-- Faces Servlet -->
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<!-- Faces Servlet Mapping -->
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.jsf</url-pattern>
	</servlet-mapping>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/spring-servlet.xml /WEB-INF/applicationContext*.xml
</param-value>
	</context-param>

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>

</web-app>

Note
It is very easy to configure any J2EE-based web application to use Spring. At the very least, you can simply add Spring’s ContextLoaderListener to your web.xml file:

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

faces-config.xml looks like this:


<?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>
	<application>
		<variable-resolver>
			org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
		<locale-config>
			<default-locale>en</default-locale>
			<supported-locale>de</supported-locale>
			<supported-locale>fr</supported-locale>
		</locale-config>
	</application>
	<!-- Managed Beans -->
	<managed-bean>
		<managed-bean-name>authorSearchCreate</managed-bean-name>
		<managed-bean-class>
			com.mattiz.web.managedbeans.AuthorSearchCreateBean
</managed-bean-class>
		<managed-bean-scope>session</managed-bean-scope>
		<managed-property>
			<property-name>serviceManager</property-name>
			<value>#{serviceManager}</value>
		</managed-property>
	</managed-bean>
	<!-- Managed Beans End -->
	<!-- Navigation Rules -->
	<navigation-rule>
		<from-view-id>/mattizpages/authors.jsp</from-view-id>
		<navigation-case>
			<from-outcome>one</from-outcome>
			<to-view-id>/mattizpages/pageOne.jsp</to-view-id>
			<redirect />
		</navigation-case>
		<navigation-case>
			<from-outcome>two</from-outcome>
			<to-view-id>/mattizpages/pageTwo.jsp</to-view-id>
			<redirect />
		</navigation-case>
	</navigation-rule>
</faces-config>

Spring configuration files

applicationContext.xml looks like this:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
	<bean id="authorLookup" class="com.mattiz.persistence.data.AuthorLookupBean">
		<property name="hibernateTemplate">
			<ref bean="hibernateTemplate" />
		</property>
	</bean>
	<bean id="serviceManager" class="com.mattiz.service.spring.DefaultServiceManager">
		<property name="authorLookup">
			<ref bean="authorLookup" />
		</property>
	</bean>
</beans>


Note:

There are two types of dependency injection: setter injection and constructor injection.

Setter Injection: Normally in all the java beans, we use setter and getter method to set and get the value of property as follows:


public class DefaultServiceManager implements ServiceManager {
....
public AuthorLookupBean getAuthorLookup() {
return authorLookup;
}
public void setAuthorLookup(AuthorLookupBean authorsLookup) {
this.authorLookup = authorsLookup;
}
}

We create an instance of the bean ‘DefaultServiceManager’ (say serviceManager) and set property as

 serviceManager.setAuthorLookup(authorLookup);

in spring configuration file as follows. To set properties that reference other beans, the “ref” subelement of “property” is used.


<bean id="serviceManager" class="com.mattiz.service.spring.DefaultServiceManager">
<property name="authorLookup">
<ref bean="authorLookup" />
</property>
</bean>
...
<bean id="authorLookup" class="com.mattiz.persistence.data.AuthorLookupBean">
...
</bean>

Constructor injection;: For constructor injection, we use constructor with parameters as shown below:


public class namebean {
	String name;

	public namebean(String a) {
		name = a;
	}
}

We set the property ‘name’ while creating an instance of the bean ‘namebean’ as namebean bean1 = new namebean(“tom”);

Here we use the constructor-arg element to set the the property by constructor injection as


<bean id="bean1" class="namebean">
	<constructor-arg>
		<value>My Bean Value</value>
	</constructor-arg>
</bean>

OR here


<bean id="mattiz.pageSize" class="java.lang.Integer">
	<constructor-arg value="5000"></constructor-arg>
</bean>

spring-servlet.xml looks like this:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!-- - Application context definition for "springapp" DispatcherServlet. -->
<beans>
	<!-- Business Layer beans definition -->
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass">
			<value>org.springframework.web.servlet.view.JstlView</value>
		</property>
	</bean>
	<!-- MySQL DataSource Definition -->
	<bean id="dataSourceMySQL" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost:3306/AUTHORS" />
		<property name="username" value="admin" />
		<property name="password" value="admin" />
	</bean>
	<!-- Hibernate SessionFactory Definition -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="mappingJarLocations">
			<value>WEB-INF/lib/mattiz.jar</value>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
				<prop key="hibernate.show_sql">true</prop>
			</props>
		</property>
		<property name="dataSource">
			<ref local="dataSourceMySQL" />
		</property>
	</bean>
	<!-- Hibernate Template Defintion -->
	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory">
			<ref local="sessionFactory" />
		</property>
		<property name="cacheQueries" value="false" />
		<property name="jdbcExceptionTranslator">
			<ref local="jdbcExceptionTranslator" />
		</property>
	</bean>
	<bean id="jdbcExceptionTranslator"
		class="org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator">
		<property name="dataSource">
			<ref local="dataSourceMySQL" />
		</property>
	</bean>
</beans>

Note
You configure your database driver in spring using datasource “org.springframework.jdbc.datasource.DriverManagerDataSource”. In this example we use org.apache.commons.dbcp.BasicDataSource


<bean id="dataSourceMySQL" class="org.apache.commons.dbcp.BasicDataSource"
	destroy-method="close">
	<property name="driverClassName" value="com.mysql.jdbc.Driver" />
	<property name="url" value="jdbc:mysql://localhost:3306/AUTHORS" />
	<property name="username" value="admin" />
	<property name="password" value="admin" />
</bean>

You can configure JNDI instead of datasource in spring configuration file using “org.springframework.jndi.JndiObjectFactoryBean”. Example here:


<bean id="dataSourceMySQL" class="org.springframework.jndi.JndiObjectFactoryBean">
	<property name="jndiName" value="java:/dbpool" />
</bean>

build.xml looks like this:


<?xml version="1.0"?>
<project name="mattiz" default="deploy" basedir=".">
	<!-- Grab the environment variables we need -->
	<property environment="env" />
	<property name="DEPLOY_LOC" value="${env.JBOSS_HOME}/server/default/deploy" />
	<!-- Base Properties -->
	<property name="src" value="src/server" />
	<property name="build_root" value="build" />
	<property name="build_dir" value="build/mattiz" />
	<property name="conf_dir" value="conf" />
	<property name="lib_dir" value="lib/third-party" />
	<property name="web.dir" value="src/webpages" />
	<property name="output.filename" value="${ant.project.name}.war" />
	<property name="classes_dest" value="build/mattiz/WEB-INF/classes" />
	<property name="output.project.jar" value="${ant.project.name}.jar" />
	<!-- classpath containing ALL jars (for building) -->
	<path id="build_classpath">
		<pathelement path="${classpath}" />
		<fileset dir="${lib_dir}">
			<include name="**/*.jar" />
		</fileset>
		<pathelement location="${classes_dest}" />
	</path>
	<!-- target: clean -->
	<target name="clean" description="--> clean build">
		<!-- kill the contents of build -->
		<delete failonerror="false" includeemptydirs="true">
			<fileset dir="${build_root}" includes="**/*" />
		</delete>
	</target>
	<!-- target: undeploy -->
	<target name="undeploy" description="--> removes war from app server">
		<delete file="${DEPLOY_LOC}/${output.filename}" />
		<delete dir="${DEPLOY_LOC}/${output.filename}" />
	</target>
	<!-- target: deploy -->
	<target name="deploy" depends="clean, package" description="--> deploys war to app server">
		<copy file="${build_root}/${output.filename}" tofile="${DEPLOY_LOC}/${output.filename}"
			overwrite="true" />
	</target>
	<!-- target: package Construct a war in the build dir -->
	<target name="package" depends="build">
		<copy todir="${build_dir}">
			<fileset dir="${web.dir}" />
		</copy>
		<!-- copy the deploy libs to lib -->
		<copy overwrite="true" todir="${build_dir}/WEB-INF/lib">
			<fileset dir="${lib_dir}" />
		</copy>
		<!-- copy the xmls to WEB-INF -->
		<copy overwrite="true" todir="${build_dir}/WEB-INF">
			<fileset dir="${conf_dir}/jbossWebRoot/WEB-INF" />
		</copy>
		<!-- copy the Hibernate mapping files to the classes tree -->
		<copy overwrite="true" todir="${classes_dest}">
			<fileset dir="src/server" excludes="**/*.java" />
		</copy>
		<!-- copy the spring files to META-INF -->
		<copy overwrite="true" todir="${build_dir}/WEB-INF">
			<fileset dir="${conf_dir}/spring" includes="*" />
		</copy>
		<!-- jar up the classes (and any config files in the class tree) -->
		<jar destfile="${build_dir}/WEB-INF/lib/${output.project.jar}"
			basedir="${build_dir}/WEB-INF/classes" includes="**/*.class,**/*.xml"
			excludes="*.txt" />
		<!-- delete the classes directory (because it's already in the jar in WEB-INF/lib -->
		<delete dir="${build_dir}/WEB-INF/classes" />
		<!-- make the war -->
		<jar destfile="${build_root}/${output.filename}" basedir="${build_dir}"
			includes="**" excludes="**/.*" />
	</target>
	<!-- target: build Build class files to the build dir (not to the src dir) -->
	<target name="build" description="builds project src">
		<mkdir dir="${classes_dest}" />
		<javac srcdir="src" destdir="${classes_dest}" classpathref="build_classpath"
			debug="yes" source="1.5" />
	</target>
</project>

Authors.java


package com.mattiz.persistence.beans;

public class Authors {
	String author;
	String isbn_Code;

	public String getAuthor() {
		return author;
	}

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

	public String getIsbn_Code() {
		return isbn_Code;
	}

	public void setIsbn_Code(String isbn_Code) {
		this.isbn_Code = isbn_Code;
	}
}

Authors.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" >

<hibernate-mapping>
	<class name="com.mattiz.persistence.beans.Authors" table="AUTHORS"
		lazy="false">
		<id name="isbn_Code" type="java.lang.String" column="ISBN_CODE"
			length="10" />
		<property name="author" type="java.lang.String" column="AUTHOR"
			length="50" />
	</class>
</hibernate-mapping>

AuthorLookupBean.java


package com.mattiz.persistence.data;

import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.mattiz.persistence.beans.Authors;
import com.mattiz.service.spring.AuthorsBean;

public class AuthorLookupBean extends HibernateDaoSupport {

	public AuthorsBean lookupIsbn(String isbn) throws DataAccessException {
		// List l = getHibernateTemplate().find(
		// "from Authors author where author.isbnCode = ?", isbn);//use when
		// isbn is not PK
		Authors author = null;
		author = (Authors) getHibernateTemplate().load(Authors.class, isbn);
		AuthorsBean authorsBean = new AuthorsBean();
		authorsBean.setAuthor(author.getAuthor());
		authorsBean.setIsbnCode(author.getIsbn_Code());
		return authorsBean;
	}

	public void insertAuthor(String isbn, String authorName)
			throws DataAccessException {
		Authors authors = new Authors();
		authors.setAuthor(authorName);
		authors.setIsbn_Code(isbn);
		getHibernateTemplate().saveOrUpdate(authors);
	}
}

Note
Hibernate provides the load() method and a get method:
author = (Authors) getHibernateTemplate().load(Authors.class, isbn);
OR
author = (Authors)session.load(Authors.class, isbn);
If load() can’t find the object in the cache or database, an exception is thrown. The load() method never returns null. Choosing between get() and load() is easy: If you’re certain the persistent object exists, and nonexistence would be considered exceptional, load() is a good option. If you aren’t certain there is a persistent instance with the given
identifier, use get() and test the return value to see if it’s null.

Note on Hibernate DAO support
Spring’s HibernateDaoSupport class is a convenient super class for Hibernate DAOs. It has handy methods you can call to get a Hibernate Session, or a SessionFactory. The most convenient method is getHibernateTemplate(), which returns a HibernateTemplate. This template wraps Hibernate checked exceptions with runtime exceptions, allowing your DAO interfaces to be Hibernate exception-free.

Note on Hibernate Session

Hibernate Session is the main runtime interface between a Java application and Hibernate. SessionFactory allows applications to create hibernate session by reading hibernate configurations file hibernate.cfg.xml.

// Initialize the Hibernate environment
Configuration cfg = new Configuration().configure();
// Create the session factory
SessionFactory factory = cfg.buildSessionFactory();
// Obtain the new session object
Session session = factory.openSession();

The call to Configuration().configure() loads the hibernate.cfg.xml configuration file and initializes the Hibernate environment. Once the configuration is initialized, you can make any additional modifications you desire programmatically. However, you must make these modifications prior to creating the SessionFactory instance. An instance of SessionFactory is typically created once and used to create all sessions related to a given context.
The main function of the Session is to offer create, read and delete operations for instances of mapped entity classes.

A Hibernate Session object represents a single unit-of-work for a given data store and is opened by a SessionFactory instance. You must close Sessions when all work for a transaction is completed. The following illustrates a typical Hibernate session:


Session session = null;
Authors author = null;
Transaction tx = null;
try {
session = factory.openSession();
tx = session.beginTransaction();
user = (Authors)session.load(Authors.class, isbn);
tx.commit();
} catch(Exception e) {
if (tx != null) {
try {
tx.rollback();
} catch (HibernateException e1) {
throw new DAOException(e1.toString()); }
} throw new DAOException(e.toString());
} finally {
if (session != null) {
try {
session.close();
} catch (HibernateException e) { }
}
}

AuthorsBean.java


package com.mattiz.service.spring;

public class AuthorsBean {
	String author;
	String isbnCode;

	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;
	}
}

DefaultServiceManager.java


package com.mattiz.service.spring;

import com.mattiz.persistence.data.AuthorLookupBean;
import com.mattiz.service.spring.AuthorsBean;

public class DefaultServiceManager implements ServiceManager {
	private AuthorLookupBean authorLookup;

	public void addAuthor(String isbnCode, String author) {
		authorLookup.insertAuthor(isbnCode, author);
	}

	public AuthorsBean findAuthor(String isbnCode) {
		AuthorsBean authorsBean = authorLookup.lookupIsbn(isbnCode);
		return authorsBean;
	}

	public AuthorLookupBean getAuthorLookup() {
		return authorLookup;
	}

	public void setAuthorLookup(AuthorLookupBean authorsLookup) {
		this.authorLookup = authorsLookup;
	}
}

ServiceManager.java


package com.mattiz.service.spring;

public interface ServiceManager {
	public void addAuthor(String isbnCode, String author);

	public AuthorsBean findAuthor(String isbnCode);
}

AuthorSearchCreateBean.java


package com.mattiz.web.managedbeans;

import com.mattiz.persistence.data.AuthorLookupBean;
import com.mattiz.service.spring.AuthorsBean;
import com.mattiz.service.spring.ServiceManager;

public class AuthorSearchCreateBean {
	private String isbnCode;
	private String author;
	private AuthorsBean authorsBean;
	private ServiceManager serviceManager;
	private AuthorLookupBean authorLookup;

	public ServiceManager getServiceManager() {
		return serviceManager;
	}

	public void setServiceManager(ServiceManager serviceManager) {
		this.serviceManager = serviceManager;
	}

	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() {
		serviceManager.addAuthor(isbnCode, author);
		System.out.println("Return from AuthorsSearchCreateBean:: add Author");
		return "two";
	}

	public String findAuthor() {
		authorsBean = serviceManager.findAuthor(isbnCode);
		isbnCode = authorsBean.getIsbnCode();
		author = authorsBean.getAuthor();
		System.out.println("Return from AuthorsSearchCreateBean:: find Author");
		return "one";
	}

	public AuthorLookupBean getAuthorLookup() {
		return authorLookup;
	}

	public void setAuthorLookup(AuthorLookupBean authorLookup) {
		this.authorLookup = authorLookup;
	}
}

I have used the following jars from the spring-framework-2.0.6-with-dependencies.zip package
All jars under:
spring-framework-2.0.6-with-dependencies/dist
spring-framework-2.0.6-with-dependencies/dist/modules
spring-framework-2.0.6-with-dependencies/lib/hibernate
spring-framework-2.0.6-with-dependencies/lib/log4j
spring-framework-2.0.6-with-dependencies/lib/jakarta-commons – minus commons-attributes-compiler.jar

Place these in lib/third-party.

authors.jsp


<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@taglib
uri="http://java.sun.com/jsf/core" prefix="f"%>
<html>
	<body>
		<f:view>
			<h:form id="authorForm">
				<p>
					<br />
					<h:outputText value="Enter ISBN code" />
					<h:inputText value="#{authorSearchCreate.isbnCode}"
						maxlength="6" size='6' />
					<br />

					<h:outputText value="Enter name of author" />
					<h:inputText value="#{authorSearchCreate.author}"
						maxlength="6" size='6' />
					<br />
					<h:commandButton id="addAuthorId"
						action="#{authorSearchCreate.addAuthor}" value="ADD" type="submit" />
					<h:commandButton id="findAuthorId"
						action="#{authorSearchCreate.findAuthor}" value="FIND" type="submit" />
				</p>
			</h:form>
		</f:view>
	</body>
</html>

pageOne.jsp


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@
taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib
uri="http://java.sun.com/jsf/core" prefix="f"%>
<html>
	<body>
		<f:view>
			AUTHOR FOUND:
			<br />
				ISBN :
				<h:outputText value="#{authorSearchCreate.isbnCode}" />
				<br />
				AUTHOR :
				<h:outputText value="#{authorSearchCreate.author}" />
				<br />
		</f:view>
	</body>
</html>

pageTwo.jsp


<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@
taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib
uri="http://java.sun.com/jsf/core" prefix="f"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<body>
		<f:view>
			AUTHOR ADDED WITH ISBN
		</f:view>
	</body>
</html>

index.jsp


<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
	<head></head>
	<body>
		<jsp:forward page="/mattizpages/authors.jsf" />
	</body>
</html>

The war file has the following structure:

<mattiz.war>
    index.jsp
    <meta-INF>
    <mattizpages>
        authors.jsp
        pageOne.jsp
        pageTwo.jsp
    <web-INF>
        applicationContext.xml
        faces-config.xml
        spring-servlet.xml
        web.xml
        spring.tld
        <lib>
           {jars mentioned above AND mattiz.jar}
        <<mattiz.jar>>
            <meta-INF>
            <com>
               <mattiz>
                  <persistence>
                      <beans>
                          Authors.java
                          Authors.hbm.xml
                      <data>
                          AuthorLookupBean.java
                  <service>
                      <spring>
                          AuthorsBean.java
                          DefaultServiceManager.java
                          ServiceManager.java
                  <web>
                      <managedbeans>
                          AuthorSearchCreateBean.java

To run the application perform the following steps:
1.set JBOSS_HOME and ANT_HOME environment variables to appropriate folders containing the

<bin>

folder in ant and jboss. Also set

<ant>/<bin>

in your path variable.
2. construct work folder as described above
3.Open dos prompt at work folder to build project – “ant deploy”
To redeploy – “ant undeploy” – and then – “ant deploy”
When you run build.bat at the dos prompt, the files in

<src>

folder are compiled and appropriate class files are placed in folder, jar and war files are created and the war file is deployed to

<server>/<default>

folder.
Start jboss:

Type the following url on the browser:

http://localhost:8080/mattiz/index.jsp

Download source code here Simple_Spring_Hibernate_Example