Spring is an open source development framework that helps developers make the development process much better. Spring is known for DI (dependency injection), IoC (inversion of control), AOP (aspects-oriented programming), core and test container, data access/integration with JDBC, ORM, JMS(Java Messaging Service), web integration with servlet, portlet, and other frameworks, such as Struts, and Spring DAO (data access object) support. We can use the Spring framework in either a Java Standalone application or a JEE enterprise application.
The official site for Spring is https://spring.io, which gives detailed information about all the projects by Spring, and http://projects.spring.io/spring-framework/, which is for the Spring framework.
In this recipe, we will take a look at how to integrate hibernate with Spring using a Spring DAO pattern. Also, we will assume that you have a basic knowledge of patterns, Maven, and Spring core.
Before moving forward, let's understand DAO.
DAO stands for data access object. It is a pattern that provides an abstract interface layer to access the database or a persistent layer using some predefined methods.
Generally, we have two different styles of DAO.
Save
, Delete
, Update
, Get by id
, and so on. This type of DAO is useful when we have to perform a common operation across the application.Save
, Delete
, Update
, and Get by id
, and it may have its own methods as well.In this example, we will use the DAO per class method.
Here, we will create a Maven project, so all project dependencies mentioned will be in pom.xml
:
Source file: pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.packt</groupId> <artifactId>SpringHibernateExample</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>SpringHiber Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <spring-framework.version>4.0.3.RELEASE</spring-framework.version> <hibernate.version>4.3.5.Final</hibernate.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring-framework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring-framework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring-framework.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.9</version> </dependency> </dependencies> <build> <finalName>SpringHibernateExample</finalName> </build> </project>
Use the following script to create the tables if you are not using hbm2dll=create|update
:
Table: film
create table film ( id bigint not null auto_increment, name varchar(255), releaseYear bigint, primary key (id) );
A model class is the same as a POJO. Execute the following code:
Source file: Film.java
package com.packt.modal; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "film") public class Film { public Film() { } public Film(String name, long releaseYear) { super(); this.name = name; this.releaseYear = releaseYear; } @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; @Column private String name; @Column private long releaseYear; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getReleaseYear() { return releaseYear; } public void setReleaseYear(long releaseYear) { this.releaseYear = releaseYear; } @Override public String toString() { return "Film [id=" + id + ", name=" + name + ", releaseYear=" + releaseYear + "]"; } }
Here, we will create an interface for the film
class by adding the following code:
Source file: FilmDao.java
package com.packt.dao; import java.util.List; import com.packt.modal.Film; public interface FilmDao { public void save(Film film); public List<Film> getAll(); public Film getById(long filmId); }
Spring is known for dependency injection, where it allows the user to inject a dependency from a hard code and has the facility to provide the configuration via XML. Here, we will create spring.xml
in which we will write all the beans that are used at runtime:
Source file: spring.xml
<?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: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/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <!-- Line 3 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!-- Line 4 --> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <!-- Line 5 --> <property name="url" value="jdbc:mysql://localhost:3306/springHibernateIntegration" /> <!-- Line 6 --> <property name="username" value="root" /> <!-- Line 7 --> <property name="password" value="root" /> </bean> <!-- Line 9 --> <bean id="hibernate4AnnotatedSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <!-- Line 10 --> <property name="dataSource" ref="dataSource" /> <!-- Line 11 --> <property name="annotatedClasses"> <list> <!-- Line 13 --> <value>com.packt.modal.Film</value> </list> </property> /* Line 16 */ <property name="hibernateProperties"> <props> /* Line 18 */ <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </prop> <prop key="hibernate.current_session_context_class">thread</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">create</prop> </props> </property> </bean> /* Line 26 */ <bean id="filmDao" class="com.packt.dao.FilmDaoImpl"> /* Line 27 */ <property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" /> </bean> </beans>
Here, Line 3
creates a bean with id
, dataSource
, which means that it creates an instance of the org.springframework.jdbc.datasource.DriverManagerDataSource
class, which is mentioned in the class attribute of the bean.
The properties are shown in Lines 4
, 5
, 6
, and 7
, which are driverClassName
, url
, username
, and password
respectively. They are fields declared in the org.springframework.jdbc.datasource.DriverManagerDataSource
class and are used to provide the database-related configuration.
The code shown in Lines 4
, 5
, 6
, and 7
uses a setter-based injection to inject the value in to the bean.
The bean declared in Line 9
is used to create the object of SessionFactory
, which we created using the hibernate.cfg.xml
file in the core hibernate application.
The code written in Line 10
provides a reference to the dataSource
bean to use the database property.
The code written in Line 13
shows the classes used in the application, so it will be scanned at the start of the application.
The code written in Line 16
is used to provide a hibernate-specific property to SessionFactory
.
Line 26
shows the initialization of FilmDaoImpl
, and Line 27
injects the object of SessionFactory
into the FilmDaoImpl
class. So, we can use it directly without creating an object of that class using a new keyword as Spring will create an instance of the particular class for us.
In this section, we will discuss the implementation of the FilmDao
interface and main
class to run our code using the main
method.
This shows the implementation of the FilmDao.java
interface:
Source File: FilmDaoImpl.java
package com.packt.dao; import java.util.List; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.criterion.Restrictions; import com.packt.modal.Film; public class FilmDaoImpl implements FilmDao { SessionFactory sessionFactory; /* Line 17 */ public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } /* Line 21 */ public void save(Film film) { Session session = this.sessionFactory.openSession(); Transaction tx = session.beginTransaction(); session.saveOrUpdate(film); tx.commit(); session.close(); } /* Line 29 */ public List<Film> getAll() { Session session = this.sessionFactory.openSession(); List<Film> filmList = session.createQuery("from Film").list(); session.close(); return filmList; } /* Line 36 */ public Film getById(long filmId) { Session session = this.sessionFactory.openSession(); Criteria criteria = session.createCriteria(Film.class); criteria.add(Restrictions.eq("id", filmId)); Film film = (Film) criteria.uniqueResult(); session.close(); return film; } }
The FileDaoImpl
class implements the FileDao
interface; so, it shows the implementation for all the methods defined in the interface.
The setter written in Line 17
is used to inject SessionFactory
in this class. Also, Line 21
shows the implementation of the save()
method, Line 29
shows the implementation of the getAll
() method, and Line 36
shows the implementation of the getById()
method.
Now, the following code shows an executable class that is used to test all the functionalities:
Source file: TestApp.java
package com.packt.common; import java.util.List; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.packt.dao.FilmDao; import com.packt.modal.Film; public class TestApp { public static void main(String[] args) { /* Line 14 */ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); /* Line 16 */FilmDao filmDao = (FilmDao) context.getBean("filmDao"); /* Line 18 */Film film1 = new Film("Film 1", 2013); /* Line 19 */filmDao.save(film1); /* Line 20 */System.out.println("Film Saved: " + film1); /* Line 22 */Film film2 = new Film("Film 2", 2014); /* Line 23 */filmDao.save(film2); /* Line 24 */System.out.println("Film Saved: " + film2); /* Line 26 */System.out.println(" All Film List"); /* Line 27 */List<Film> films = filmDao.getAll(); /* Line 28 */for (Film filmObj : films) { /* Line 29 */ System.out.println(filmObj); /* Line 30 */} /* Line 32 */System.out.println(" Get Film by id 1"); /* Line 33 */Film film = filmDao.getById(1); /* Line 34 */System.out.println(film); /* Line 35 */context.close(); } }
The output will be as follows:
Hibernate: drop table if exists film Hibernate: create table film (id bigint not null auto_increment, name varchar(255), releaseYear bigint, primary key (id)) Hibernate: insert into film (name, releaseYear) values (?, ?) Film Saved: Film [id=1, name=Film 1, releaseYear=2013] Hibernate: insert into film (name, releaseYear) values (?, ?) Film Saved: Film [id=2, name=Film 2, releaseYear=2014] All Film List Hibernate: select film0_.id as id1_0_, film0_.name as name2_0_, film0_.releaseYear as releaseY3_0_ from film film0_ Film [id=1, name=Film 1, releaseYear=2013] Film [id=2, name=Film 2, releaseYear=2014] Get Film by id 1 Hibernate: select this_.id as id1_0_0_, this_.name as name2_0_0_, this_.releaseYear as releaseY3_0_0_ from film this_ where this_.id=? Film [id=1, name=Film 1, releaseYear=2013]
Let's consider the code line by line to understand it.
In the line, /* Line 14 */ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
, we created an instance of the ClassPathXmlApplicationContext
class and provided our bean configuration file, spring.xml
, as a constructor argument. As we used the ClassPathXmlApplicationContext
class, hibernate will look in the classpath for spring.xml
and load all the beans defined in this file.
Using the line, /* Line 16 */FilmDao filmDao = (FilmDao) context.getBean("filmDao");
, we fetched a bean from the context with id filmDao
. It will return an instance of the FilmDaoImpl
class. The bean is declared in the spring.xml
file in Line 26
: <bean id="filmDao" class="com.packt.dao.FilmDaoImpl">
.
Lines 18
to 24
are used to create a different instance of Film
and save it to the database using the DAO method, save(Film film);
.
Lines 26
to 30
are used to get all the films using the getAll();
method.
Lines 32
to 35
are used to get Film
by id
using the getById(long filmId);
method.