
In this blog I will explain how to integrate hibernate with spring. I will demonstrate through the code. This is how my folder structure will look like. It will be the simplest application and will not explain in details about either Hibernate or Spring. The folder structure is easy to understand. in the dao package i will have an interface UsersDao which will have the operation that we want to perform on the Users model class which is inside model package. The UsersDao interface will be implemented by the class inside the impl package. I have used this separation of interface and class as later if we want to change from Hibernate to some other ORM tool or any other data access mechanism it should not effect our client code as client will be calling methods on the interface rather than directly accessing the implementation. The service package will have a UserService class which will be the mediator between the client and the data access layer. I don't want client to be coupled with my data access layer. Client will call methods defined in the service class which in turn will call methods from the dao class. Another loose coupling. In the main package I have a Test class which is my java client. Inside utility package i have a HibernateUtility class which will be used to get hibernate session factory. So lets first build a simple hibernate application and then we will use spring to integrate hibernate with spring. I will using Hibernate3.6 and Spring 3.2 and Oracle11g for this demo application.
First we need Hibernated related JARs that we are going to use in the demo application. I have created a user library called Hibernate and added the hibernate related JARs in that library and included the library in the application classpath. Below are the JARs that you need.
Now that we have got all the JARs in place lets first create our model class called Users. This will be a simple entity class annotated with @Entity as this class will be representing our Users table in the database.
package com.sanjiv.model;
import javax.persistence.Entity;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
@Entity
@Table(name="Users")
public class Users{
@Id
@Column(name="USER_ID")
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="userid_seq")
@SequenceGenerator(name="userid_seq",sequenceName="userid_sequence",
allocationSize=1)
private int Id;
@Column(name="USER_NAME")
private String userName;
@Column(name="EMAIL_ID")
private String emailId;
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
}
Then comes the UsersDao interface which will have just two methods for our demo application to make it simple.
package com.sanjiv.dao;
import java.util.List;
import com.sanjiv.model.Users;
public interface UsersDao {
public void save(Users user);
public List<Users> getUsers();
}
Then comes the implementation class. As I am using hibernate as the ORM tool i will call this impl class as HibernateUserDaoImpl which will implement the UsersDao interface.
package com.sanjiv.dao.impl;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.sanjiv.dao.UsersDao;
import com.sanjiv.model.Users;
public class HibernateUserDaoImpl implements UsersDao{
SessionFactory sessionFactory;
public HibernateUserDaoImpl(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public void save(Users user) {
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
session.save(user);
tx.commit();
//session.close();
}
@Override
public List<Users> getUsers() {
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
List<Users> usersList = session.createQuery("from Users").list();
tx.commit();
return usersList;
}
}
Then the service class on which the clients will call the methods on. Clients need not access the DAO classes directly.
package com.sanjiv.serivce;
import java.util.List;
import com.sanjiv.dao.UsersDao;
import com.sanjiv.model.Users;
public class UserService {
private UsersDao usersDao;
public UserService(UsersDao usersDao){
this.usersDao = usersDao;
}
public UsersDao getUsersDao() {
return usersDao;
}
public void setUsersDao(UsersDao usersDao) {
this.usersDao = usersDao;
}
public void save(Users user){
usersDao.save(user);
}
public List<Users> getUsers(){
return usersDao.getUsers();
}
}
Now lets configure hibernate related propeties in hibernate.cfg.xml file. The name of the file can be any arbitary name its just the convention to name it hibernate.cfg.xml. All the database related information will go in this config file. Hibernate uses information from this file to create session factory objects. I am using Oracle as my databse. You can use any databse of your choice and replace the vlaues in the file with the corresponding values as per your DB configuraiton. I will also need ojdbc6.jar in my classpath to load oracle driver. If you are using another DB don't forget to add the jar in your classpath for the DB vendor.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- session-factory name=""> -->
<session-factory>
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:devDB</property>
<property name="hibernate.connection.username">system</property>
<property name="hibernate.connection.password">admin123</property>
<property name="hibernate.connection.pool_size">1</property>
<property name="show_sql">true</property>
<property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
<property name="hibernate.current_session_context_class">thread</property>
<!-- property name="mappingDirectoryLocations">classpath:WEB-INF/classes/hibernate</property-->
<!-- Mapping classes -->
<mapping class="com.sanjiv.model.Users"/>
</session-factory>
</hibernate-configuration>
Finally HibernateUtility class which is responsible to load session factory from the config file.
package com.sanjiv.utility;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtility {
private static SessionFactory sessionFactory;
public static SessionFactory buildSessionFacroty(){
return new Configuration().configure("hibernate.cfg.xml")
.buildSessionFactory();
}
}
Try to run this code using the client application by inserting some Users in the table-
package com.sanjiv.main;
import com.sanjiv.dao.UsersDao;
import com.sanjiv.dao.impl.HibernateUserDaoImpl;
import com.sanjiv.model.Users;
import com.sanjiv.serivce.UserService;
import com.sanjiv.utility.HibernateUtility;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Users user = new Users();
UserService userService = new UserService(new HibernateUserDaoImpl(HibernateUtility.buildSessionFacroty()));
//UsersDao userDao = );
user.setUserName("Sanjiv Kumar");
user.setEmailId("sanjiv@kumar.com");
userService.save(user);
System.out.println(userService.getUsers().size());
//HibernateUtility.buildSessionFacroty().close();
}
}
If you run the sample code given above you will be able to see output like below on your console-
Hibernate: select userid_sequence.nextval from dual
Hibernate: insert into Users (EMAIL_ID, USER_NAME, USER_ID) values (?, ?, ?)
Hibernate: select users0_.USER_ID as USER1_0_, users0_.EMAIL_ID as EMAIL2_0_, users0_.USER_NAME as USER3_0_ from Users users0_
1
In step two we will integrate the same application with Spring.
Ok, so lets go ahead and add spring related JARs to the application. Below are the JARs that we need to add-
Ok, so lets go ahead and add spring related JARs to the application. Below are the JARs that we need to add-
Now lets create the spring configuration file in our classpath and name it spring.xml and add entry for our UserService and UsersDao in its beans declaration-
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<bean id="usersDao" class="com.sanjiv.dao.impl.HibernateUserDaoImpl">
</bean>
<bean id="userService" class="com.sanjiv.serivce.UserService">
<property name="usersDao" ref="usersDao" />
</bean>
</beans>
We will use spring LocalSessionFactoryBean class to integrate hibernate with spring. So lets configure this class in beans declaration and will pass the hibernate.cfg.xml file path to its configLocation property.
<!-- Hibernate3 XML SessionFactory Bean definition-->
<bean id="hibernate3SessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>hibernate.cfg.xml</value>
</property>
</bean>
Our dao class has a reference to session factory object. So now instead of using hibernate's session factory it will use spring's LocalSessionFactoryBean as its session factory. So add this as spring beans property as ref parameter. So the complete spring.xml file will look like this-
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<bean id="usersDao" class="com.sanjiv.dao.impl.HibernateUserDaoImpl">
<property name="sessionFactory" ref="hibernate3SessionFactory" />
</bean>
<bean id="userService" class="com.sanjiv.serivce.UserService">
<property name="usersDao" ref="usersDao" />
</bean>
<!-- Hibernate3 XML SessionFactory Bean definition-->
<bean id="hibernate3SessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation">
<value>hibernate.cfg.xml</value>
</property>
</bean>
</beans>
Now we will make some adjustment in our client code. It will use dependency injection to get the instance of UserSerivce bean. Dont forget to add no-arg constructor to all your bean classes else the bean will fail to intialize. Thats it, we are done now. Lets try to run our client and see the sample outpout. One more thing Spring uses commons-loggings for logging so don't forget to add commons-loggins.jar as well. Here is my modified client code-
import com.sanjiv.dao.UsersDao;
import com.sanjiv.dao.impl.HibernateUserDaoImpl;
import com.sanjiv.model.Users;
import com.sanjiv.serivce.UserService;
import com.sanjiv.utility.HibernateUtility;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) context.getBean("userService");
Users user = new Users();
user.setUserName("Rahul Ranjan");
user.setEmailId("rahul.ranjan@gmail.com");
userService.save(user);
System.out.println(userService.getUsers().size());
//HibernateUtility.buildSessionFacroty().close();
}
}
Below is the output from console-
Hibernate: select userid_sequence.nextval from dual
Hibernate: insert into Users (EMAIL_ID, USER_NAME, USER_ID) values (?, ?, ?)
Hibernate: select users0_.USER_ID as USER1_0_, users0_.EMAIL_ID as EMAIL2_0_, users0_.USER_NAME as USER3_0_ from Users users0_
1
Below is the output form users table from the database
Hope you enjoyed reading it.
Thanks for reading.
Thanks for reading.




No comments:
Post a Comment