Notes on Spring and Hibernate

Q# How do you implement transaction handling in spring and hibernate?

This looks like a very good explanation of spring and hibernate transaction handling:
http://java.dzone.com/articles/spring-hibernate-persistence
It first discusses hibernate the traditional way, using session etc.then describes hibernate using spring templates.
With Spring, you do not need to implement code for obtaining Session objects, starting and committing transactions, and handling Hibernate exceptions. Instead, you use a HibernateTemplate instance to delegate persistence calls to Hibernate, without direct interaction with Hibernate.
This page would clear any questions about spring/hibernate including transaction handling, etc.
Also
http://static.springsource.org/spring/docs/2.0.8/reference/transaction.html
Spring declarative transaction types
@Transactional
Enum Constants
Enum Constant and Description
MANDATORY
Support a current transaction, throw an exception if none exists.
NESTED
Execute within a nested transaction if a current transaction exists, behave like PROPAGATION_REQUIRED else.
NEVER
Execute non-transactionally, throw an exception if a transaction exists.
NOT_SUPPORTED
Execute non-transactionally, suspend the current transaction if one exists.
REQUIRED
Support a current transaction, create a new one if none exists.
REQUIRES_NEW
Create a new transaction, and suspend the current transaction if one exists.
SUPPORTS
Support a current transaction, execute non-transactionally if none exists.

JDBC is a Java standard for database connection. JPA isolates the Java developer from the inner workings of JDBC and database operations. Hibernate, EclipseLink, OpenJPA and Data Nucleus are famous JPA implementations. JTA is a standard for transactions, allowing for management of multiple transactions among multiple databases. JPA utilizes JDBC for database connections and SQL-related operations, and -optionally- utilizes JTA for delegating distributed transaction management details to it.

Q# How does hibernate implement caching programatically?

There are two types of caching – first-level and second-level. First-level cache is hibernate’s internal cache that it uses for optimizing. Second-level caching, is what we normally refer to as caching generally. Secondary level caching is usually implemented using an algorithm like Least Recently Used algorithm.
From
http://www.informit.com/articles/article.aspx?p=353736&seqNum=5
By storing the data in a cache instead of relying solely on the database, you may be able to significantly reduce the load on the database, and possibly to increase overall performance as well.
From
http://cuppajavamattiz.com/2010/07/30/hibernate-ehcache-and-caching/
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.

Implementing caching programatically
We specify which classes to cache and the caching params but we don’t really write code to invoke the cache.
http://www.informit.com/articles/article.aspx?p=353736&seqNum=5 #Configuring a Cache.
If you feel certain that the problems are due to the amount of traffic between your application and the database. The solution in this case may be a cache. By storing the data in a cache instead of relying solely on the database, you may be able to significantly reduce the load on the database, and possibly to increase overall performance as well.
Regardless of which cache you choose, you will need to tell Hibernate what sort of cache rules should be applied to your data. This is defined using the cache tag. You can place the cache tag in your *.hbm.xml files or in the hibernate.cfg.xml file. Alternatively, you can configure cache settings programmatically using the Configuration object.

Q# How do you configure hibernate using spring?

Hibernate Integration with Spring http://java.dzone.com/articles/spring-hibernate-persistence
http://elope.wordpress.com/2007/09/06/difference-between-jpa-and-hibernate/
When the application uses hibernate using hibernate.cfg.xml, the Session Factory configured through it is available to the DAO class.

SessionFactory sessionFactory =new Configuration().configure().buildSessionFactory();
session = sessionFactory.openSession();
Transaction tx = sesssion.beginTransaction();
Object obj = session.get(....);
session.createQuery("HQL_query");
tx.commit();
session.close();

Spring’s Hibernate Support
The datasource is configured in Spring’s application context xml. The datasource might be configured using a JNDI context as well. Spring provides support for hibernate through the HibernateDaoSupport class. The HibernateDao support wraps the HibernateTemplate which in turn wraps the Hibernate session object which in turn wraps the Hibernate Session Factory. The session factory is passed a reference to the configured datasource in the spring context. The hibernate template is an abstraction around the usual boilerplate code written when only hibernate is used; and takes care of managing transactions, handling exceptions, managing connections and delegating persistence calls to hibernate. save(), load(), get(), which is invoked on the hibernate session, can be invoked on the hibernate template as well, in addition to find() and findByCriteria() not exposed by the hibernate session.
Spring’s IOC layer also allows the DAO class to be loosely coupled from the service layer and be configured through xml files. In a spring application, the dao layer is usually separated from the business layer by a service facade pattern. Transaction management can be done decoratively instead of code.
When you use JPA with Spring the underlying Hibernate or EJB3 implementation of the persistence layer is hidden and JPA act as a wrapper over them.

The DAO class(Spring) is a wrapper over HibernateTemplate(Spring) which in turn wraps the Hibernate session object which in turn wraps the Hibernate Session Factory. Obtain session from sessionfactory, open transaction from session, commit/ rollback the transaction and close the session. Get hibernateTemplate(Spring) from SessionFactory(Hibernate) to perform the perisistence operations. Don’t work directly with session in Spring. Spring obtains instances of Session objects from the SessionFactory instance. Exceptions emerging from Hibernate are handled by the Spring layer and transactions can be managed if required declaratively by the Spring layer.

Q# Explain lazy loading and eager fetch in hibernate.

If object A has relation with object B, if you load object A, object B is not loaded from db automatically; it will be loaded only when you do getB(). Eager fetch is the opposite technique. In eager fetch B is loaded when A is loaded if A contains B. The default mechanism is lazy loading.
When to use lazy loading and when to use eager fetch:
Lazy load will not automatically load child objects. It will load child objects only when getChild() is called. Eager fetch will automatically load child objects when the parent object is loaded.
Whether to use lazy load or eager fetch depends on your performance requirements.
If you use eager fetch children were already loaded and are already in memory so accessing these objects will be faster. Memory consumption will be more because more objects are in memory even if they are not needed.If you use lazy load, child objects are loaded only when required (when getter method is invoked). Hence accessing child objects will be somewhat slower but will use lesser memory since objects are loaded only if they are required.
http://powerdream5.wordpress.com/2007/11/09/eager-loading-in-hibernate/

Q# Give some advantages of JPA over hibernate. When do we use hibernate and when do we use JPA?

JPA is a wrapper around ORM technology such as EJB3 and Hibernate among others.
Hibernate 3.0 as well as EJB3 implement and support JPA. Code written using JPA uses a standard Java API so that it is generic and implementation agnostic. I could switch hibernate to use something else like iBatis etc. Beneath JPA, the underlying persistence mechanism could be hibernate or toplink or jbatis etc. JPA delegates the database transactions to the underlying persistence layer. The underlying persistence mechanism could be changed anytime and the JPA code wouldn’t change.

And hibernate 3.0 implements the JPA specification so TopLink and other O/R mapping framework.So your code depends upon JPA Api and its implementation is supplied by any JPA impl vendor framework. So in effect if you use JPA , you are using a standard Java Api and not some orthogonal Api and hence you have flexibility in your system. Say initially you have used Hibernate but now want to shift to Other framework.That means JPA supports pluggable persistence providers. JPA specification is heavily influenced by current O/R mapping frameworks like Hibernate and Top-Link.

Q# What is cascade-all in Hibernate? What are its advantages?

In a hibernate mapping file, if you specify cascade=”none” means that saving or deleting first hibernate object has no affect on related object. cascade=”save” means if first object is saved it automatically saves the related object. Similarly cascade delete will delete related object. cascade=”all” is everything save, delete etc even if they are related with foreign keys. The FK constraints etc. everything gets deleted and hibernate takes care of that.
eg.
The code to add a Child looks like this

Parent p = (Parent) session.load(Parent.class, pid);
Child c = new Child();
p.addChild(c);
session.save(c);
session.flush()

You can address the frustrations of the explicit call to save() by using cascades.

Cascade in hibernate (saving child objects as well) and cascade in sql(deleting rows in parent table when fk related child tables rows are deleted)

Q# What is dirty checking in hibernate? What are its advantages?

Dirty checking is hibernate is an internal mechanism that ensures that the value of the hibernate POJO object matches what is in the database(synchronizes). If the value does not match it is said to be “dirty” and hence value is refreshed from the database. Hibernate updates only “dirty” objects – only objects that have changed. Hibernate keeps track of which objects are dirty and occasionally “flushes” to ensure the objects are in sync with the db. The advantages of dirty checking is if hibernate doesn’t keep track of which objects are dirty it would have to update all objects that were loaded even if they didn’t change at the final commit of the transaction.

What are bean scopes in Spring?

1. singleton(default*)
Scopes a single bean definition to a single object instance per Spring IoC container.
2. prototype
Scopes a single bean definition to any number of object instances.
3. request
Scopes a single bean definition to the lifecycle of a single HTTP request; that is each and every HTTP request will have its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
4. session
Scopes a single bean definition to the lifecycle of a HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
5. global session
Scopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a portlet context. Only valid in the context of a web-aware Spring ApplicationContext.

Difference between a Java singleton and a Spring singleton

The Java singleton is scoped by the Java class loader, the Spring singleton is scoped by the container context.
Which basically means that, in Java, you can be sure a singleton is a truly a singleton only within the context of the class loader which loaded it. Other class loaders should be capable of creating another instance of it (provided the class loaders are not in the same class loader hierarchy), despite of all your efforts in code to try to prevent it.
In Spring, if you could load your singleton class in two different contexts and then again we can break the singleton concept.
In summary, Java considers something a singleton if it cannot create more than one instance of that class within a given class loader, whereas Spring would consider something a singleton if it cannot create more than one instance of a class within a given container/context.

Hibernate, ehCache and Caching

Hibernate uses caching internally. There’s always a trade off when you use caching. Without caching one observes slower times for execution, but will use less memory. Memory caching may impact the entire server or application if it runs out of memory, and memory size affects overall performance. Caching tens of thousands records doesn’t seem to be a good idea. I would imagine that ehcache has the capability to cache selectively, for instance cache some rows that are frequently used, instead of caching the entire table and strike a balance between acceptable memory taken and good speed too. If the same rows are retrieved numerous times, it is a good idea to cache those, however if different rows are retrieved each time, then it doesn’t make sense.
If the rows involved are in the thousands I would say, it is not a good idea to cache the whole table. iIt may be useful to investigate caching partially selectively based on LRU algorithm for instance. If the same rows are read again and again then we go for selective caching. If different rows are being read each time a lot of it depends on the application behavior. ehCache has some great caching techniques for selective caching of which most common is LRU (Least Recently Used algorithm)
Let us say maximum size of cache is 10 rows, a hypothetical number. Let us say User 1 reads rows 1, 2, 3, 4, 5. These rows are cached. User 2 reads rows 21, 22, 23, 24, 25, these rows are cached as well. Then if User 3 reads 31, 32, 33, 34, 35 these rows will be cached but the first five rows 1,2,3,4,5 will expire from the cache, since max number is only 10.
So if we go on calling any of 1.2,3.4.5 then we have good caching, number of hits is more. However if another user now asks for 1,2,3,4,5 and they are not in the cache, then it is a miss and these will be reloaded. So there is some tweaking that can be done about size limit.
maxElementsInMemory=”300″ means the max limit (10, in our example). memoryStoreEvictionPolicy=”LRU” is the least recently used algorigthm. There may be other algorigthms that ehCache supports.

From this http://www.mydeveloperconnection.com/html/spring-hibernate-QnA.htm :

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.
Example http://cuppajavamattiz.com/2007/09/16/using-mysql-ds-xml-and-applicationcontext-data-with-the-hibernate-example/ in applicationContext-data.xml.
Configuring Hibernate Cache
We specify which classes to cache and the caching params but we don’t really write code to invoke the cache.
http://www.informit.com/articles/article.aspx?p=353736&seqNum=5 #Configuring a Cache.
If you feel certain that the problems are due to the amount of traffic between your application and the database. The solution in this case may be a cache. By storing the data in a cache instead of relying solely on the database, you may be able to significantly reduce the load on the database, and possibly to increase overall performance as well.
Regardless of which cache you choose, you will need to tell Hibernate what sort of cache rules should be applied to your data. This is defined using the cache tag. You can place the cache tag in your *.hbm.xml files or in the hibernate.cfg.xml file. Alternatively, you can configure cache settings programmatically using the Configuration object.

Many To One Hibernate Relations

I have modified the previous standalone Hibernate application to indicate how a one to many relation between objects is handled in Hibernate. http://cuppajavamattiz.com/2008/06/14/migrating-to-a-standalone-spring-hibernate-application/ I am using the jars under the folllwing folders in spring-framework-2.5.4-with-dependencies.zip:

spring-framework-2.5.4/lib/c3p0
spring-framework-2.5.4/lib/cglib
spring-framework-2.5.4/lib/jakarta-commons
spring-framework-2.5.4/lib/dom4j
spring-framework-2.5.4/lib/hibernate
spring-framework-2.5.4/dist
spring-framework-2.5.4/lib/log4j
spring-framework-2.5.4/lib/antlr

Of course I also separately downloaded and used jta.jar and the mysql driver.

The book has a one to many relationship with the author object with one book being written by serveral authors.

You need to run the following scripts for database intialization: I have used the same database named “authors” for this purpose.

CREATE TABLE TB_AUTHOR (UID int NOT NULL default 0, FIRST_NAME varchar(15) default NULL, LAST_NAME varchar(15) default NULL, BOOK_ID varchar(10) default NULL, PRIMARY KEY (UID)) ;

CREATE TABLE TB_BOOK (ISBN_CODE varchar(10) NOT NULL default '0', TITLE varchar(25) default NULL,PRIMARY KEY (ISBN_CODE)) ;

I am only including source code for the DAO class and the domain classes and the hbm.xml files for simplicity. The client code can be rewritten using code in the previous code as a base.

The DAO class:

package com.mattiz.persistence.data;
 
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
 
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;
 
import com.mattiz.persistence.beans.Author;
import com.mattiz.persistence.beans.Book;
 
public class AuthorLookupBean {
 
    private HibernateTemplate hibernateTemplate;
 
    public void insertBook() throws DataAccessException {
        Book book = new Book();
        book.setIsbnCode("124");
        book.setTitle("The Dodo");
        book.setAuthors(new HashSet());
        book.getAuthors().add(new Author("Roy", "John"));
        book.getAuthors().add(new Author("James", "Joyce"));
        book.getAuthors().add(new Author("Jill", "Joyce"));
        book.getAuthors().add(new Author("Amy", "Watt"));
        book.getAuthors().add(new Author("Matt", "Tizz"));
        HibernateTemplate template = getHibernateTemplate();
        template.save(book);
    }
 
    public void getAuthorsFromBook() throws DataAccessException {
        String isbn = "124";
        Book book = (Book) getHibernateTemplate().load(Book.class, isbn);
        Set authors = book.getAuthors();
        Iterator iterator = authors.iterator();
        while (iterator.hasNext()) {
            Author author = (Author) iterator.next();
            System.out.println("FIRST NAME " + author.getFirstName());
            System.out.println("SECOND NAME " + author.getLastName());
        }
    }
 
    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }
 
    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }
}

The Author Domain class:

package com.mattiz.persistence.beans;

public class Author {
	public Author() {
	}

	public Author(String first, String last) {
		this.firstName = first;
		this.lastName = last;
	}

	private String firstName;
	private String lastName;
	private long id;

	public String getFirstName() {
		return firstName;
	}

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

	public String getLastName() {
		return lastName;
	}

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

	public long getId() {
		return id;
	}

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

The Book Domain class:

package com.mattiz.persistence.beans;

import java.util.Set;

public class Book {
	private String isbnCode;
	private String title;
	private Set authors;

	public String getIsbnCode() {
		return isbnCode;
	}

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

	public Set getAuthors() {
		return authors;
	}

	public void setAuthors(Set authors) {
		this.authors = authors;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}
}

The Author 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.Author" table="TB_AUTHOR"
        lazy="false">
        <id name="id" column="UID" type="long">
            <generator class="increment" />
        </id>
        <property name="firstName" type="java.lang.String" column="FIRST_NAME"
            length="25" />
        <property name="lastName" type="java.lang.String" column="LAST_NAME"
            length="25" />
    </class>
</hibernate-mapping>

Note on id generator classes in hibernate:
assigned: lets the application to assign an identifier to the object before save() is called. This is the default strategy if no generator element is specified.
increment: It generates identifiers of type long, short or int that are unique only when no other process is inserting data into the same table. It should not the used in the clustered environment.
sequence: The sequence generator uses a sequence in DB2, PostgreSQL, Oracle, SAP DB, McKoi or a generator in Interbase. The returned identifier is of type long, short or int
identity: It supports identity columns in DB2, MySQL, MS SQL Server, Sybase and HypersonicSQL. The returned identifier is of type long, short or int.
hilo: The hilo generator uses a hi/lo algorithm to efficiently generate identifiers of type long, short or int, given a table and column (by default hibernate_unique_key and next_hi respectively) as a source of hi values. The hi/lo algorithm generates identifiers that are unique only for a particular database. Do not use this generator with connections enlisted with JTA or with a user-supplied connection.
seqhilo: The seqhilo generator uses a hi/lo algorithm to efficiently generate identifiers of type long, short or int, given a named database sequence.
uuid: The uuid generator uses a 128-bit UUID algorithm to generate identifiers of type string, unique within a network (the IP address is used). The UUID is encoded as a string of hexadecimal digits of length 32.
guid: It uses a database-generated GUID string on MS SQL Server and MySQL.
native: It picks identity, sequence or hilo depending upon the capabilities of the underlying database.

select: retrieves a primary key assigned by a database trigger by selecting the row by some unique key and retrieving the primary key value.
foreign: uses the identifier of another associated object. Usually used in conjunction with a primary key association.

The Book hbml.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.Book" table="TB_BOOK"
        lazy="false">
        <id name="isbnCode" column="ISBN_CODE" type="string">
            <generator class="assigned" />
        </id>
        <set name="authors" cascade="save-update" lazy="false">
            <key column="BOOK_ID" />
            <one-to-many class="com.mattiz.persistence.beans.Author" />
        </set>
        <property name="title" type="java.lang.String" column="TITLE"
            length="50" />
    </class>
</hibernate-mapping>

Output looks something like this:


mysql> select * from tb_author;
+-----+------------+-----------+---------+
| UID | FIRST_NAME | LAST_NAME | BOOK_ID |
+-----+------------+-----------+---------+
|   1 | James      | Joyce     | 124     |
|   2 | Amy        | Watt      | 124     |
|   3 | Jill       | Joyce     | 124     |
|   4 | Roy        | John      | 124     |
|   5 | Matt       | Tizz      | 124     |
+-----+------------+-----------+---------+
5 rows in set (0.00 sec)

mysql> select * from tb_book;
+-----------+----------+
| ISBN_CODE | TITLE    |
+-----------+----------+
| 124       | The Dodo |
+-----------+----------+

You would have to clean the data in the database after each run to avoid constraint violations, or better still modify the code above to handle that!

By the way, I would like to add something: I get a classic Lazy Initialization Exception if I don’t declare the set in Book.hbm.xml as lazy=”false”, that is I let it load non-lazy. This is a workaround and should be avoided as it could raise performance issues in critical situations.
NoteLazy loading and can be achieved in hibernate using the lazy attribute. Lazy setting decides whether to load child objects while loading the Parent Object. You need to specify parent class.Lazy = true in hibernate mapping file. By default the lazy loading of the child objects is true. This make sure that the child objects are not loaded unless they are explicitly invoked in the application by calling getChild() method on parent. In this case hibernate issues a fresh database call to load the child when getChild() is actully called on the Parent object. But in some cases you do need to load the child objects when parent is loaded. Just make the lazy=false and hibernate will load the child when parent is loaded from the database. Examples: Address child of User class can be made lazy if it is not required frequently. But you may need to load the Author object for Book parent whenever you deal with the book for online bookshop.

Access source code here

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

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