When building a web application, we will sooner or later need to somehow store data entered by users and retrieve it later. In most cases the best place to keep such data is a database because it additionally provides many useful features like transactions.
Therefore, in this article I would like to show how to extend our previous Spring MVC application to use Hibernate to access database and manage transactions. The configuration details slightly depend on the database being used. In our case it will be Oracle 11gR2 database.
Configuring Hibernate session factory
Before we start we have to configure Hibernate session factory in our Spring configuration file:
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan" value="com.example.springhibernate" /> <property name="hibernateProperties"> <props> <prop key="dialect"> org.hibernate.dialect.Oracle10gDialect </prop> <prop key="hibernate.show_sql"> true </prop> <prop key="hibernate.hbm2ddl.auto"> create </prop> </props> </property> </bean>
In property dataSource we refer to the data source configured in our application server and exposed via JNDI with name java:/orcl:
<jee:jndi-lookup id="dataSource" jndi-name="java:/orcl" />
The second property packagesToScan specifies Java package to automatically scan for annotated entity classes. This way it is no longer necessary to prepare Hibernate mapping file.
Finally, the third property hibernateProperties gives us possibility to configure various Hibernate properties. In property dialect we specify that we use Oracle database, then we inform Hibernate to print issued SQL commands to the server log and to generate necessary objects (like tables) in the database. Please, note that the last option cannot be used in the production code because it may drop already existing tables in the database. We use it only to simplify the example.
Configuring transaction support
Because we plan to use Hibernate transactions and declare them using annotations, we have to add two additional elements to our Spring configuration:
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:annotation-driven/>
The first one informs Spring to instantiate HibernateTransactionManager transaction manager and associate it with the previously configured Hibernate session factory. The second one tells Spring to scan all classes for @Transactional annotation on a class or method level in order to use it with the transaction manager.
Using annotations
After we have finished the configuration, we can add standard persistence annotations to our Person entity class:
package com.example.springhibernate; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.NamedQuery; import javax.persistence.Table; @Entity @Table(name = "springhibernate_person") @NamedQuery(name = "Person.selectAll", query = "select o from Person o") public class Person implements Serializable { private static final long serialVersionUID = 3297423984732894L; @Id @GeneratedValue private int id; private String firstName; private String lastName; private Integer age; // constructor, setters and getters }
To access the database we create a simple repository class annotated with @Repository:
package com.example.springhibernate; import java.io.Serializable; import java.util.List; import org.hibernate.Query; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; @Repository @Transactional public class PersonList implements Serializable { private static final long serialVersionUID = 324589274837L; @Autowired private SessionFactory sessionFactory; @Transactional public void addPerson(Person person) { sessionFactory.getCurrentSession().save(person); } @Transactional public List<Person> getAll() { Query query = sessionFactory.getCurrentSession().getNamedQuery("Person.selectAll"); return (List<Person>) query.list(); } }
In this class we obtain a reference to the correct SessionFactory instance using plain @Autowired annotation. Additionally, both methods of this class are annotated with @Transactional to inform Spring that these methods should be executed in a transaction.
Conclusion
Configuration of Hibernate in Spring is not very difficult but still requires setting several parameters specific to the environment in XML configuration files. The rest of the code is totally independent of it so changes necessary to switch to the other database or application server are limited to few lines of the configuration.
The example above uses version 4 of Hibernate but switching to version 3 is pretty simple and requires only replacing hibernate4 by hibernate3 in two places in Spring XML file.
The complete source code of the example can be found at GitHub.
Reblogged this on Dinesh Ram Kali..