spring4 hibernate integration example + annotation / Java Config

spring4 hibernate integration example + annotation / Java Config thumbnail
28K
By Dhiraj 01 January, 2018

There are numerous spring hibernate integration example available on the web but most of them are not using java configurations. But many spring app these days are being developed using java config. Hnce, today we will be dicussing about spring hibernate integration example with complete java configurations, no xml at all.

This post can be considered as an upgradation of my previous post where we discussed Spring AngularJS intgration but without DB connection. Today in this post we will be discussing about how to integrate spring and hibernate with angularjs as a client side framework. Hence, most of the common code configurations between this and previous post will not be mentioned here. Still, you can download the complete source code at the end of the article.

Table of Contents
1. Environment Setup
2. Project Structure
3. Maven Dependencies
4. Spring Bean Configuration
5. Configuring Hikari Datasource
6. Server Side
6.1 Spring Controller
6.2 Hibernate Entity
7. Sample Insert Statement
8. Client Side Code
9. Run Application

Environment Setup

1. JDK 8 2. Spring 4 3. Hibernate 4 4. Intellij Idea/ eclipse 5. Angular Js and bootstrap library 6. Maven 7. Apache tomcat

Project Structure

spring-hibernate-project-structure

Maven Dependencies

Following are the maven dependencies for spring and hibernate integration.

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.developerstack</groupId>
    <artifactId>jms-spring-integration</artifactId>
    <version>0.1.0</version>

    <properties>
        <spring.version>4.1.0.RELEASE</spring.version>
		<hibernate.version>4.3.5.Final</hibernate.version>
		<jackson.version>2.7.2</jackson.version>
    </properties>

    <dependencies>
		<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
        </dependency>
		
		<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
			<version>${spring.version}</version>
		</dependency>
		
		<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
			<version>${spring.version}</version>
		</dependency>
		
		<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>
		
		<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>
		
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		
		<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
			<version>${spring.version}</version>
		</dependency>
		
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
			<version>${hibernate.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>
		
		<dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
			<version>1.4</version>
		</dependency>
		
		<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
			<version>${jackson.version}</version>
		</dependency>
		
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
			<version>${jackson.version}</version>
		</dependency>
		
		<dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
			<version>2.6.2</version>
		</dependency>
		
    </dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.6</version>
				<configuration>
					<failOnMissingWebXml>false</failOnMissingWebXml$gt
				</configuration>
			</plugin>
		</plugins>
	</build>
	
</project>

Spring Bean Configuration

This configuration is responsible to initialize spring based web application. We have implemented WebApplicationInitializer.java to configure the ServletContext programmatically with all request coming to server will be intercepted by DispatcherServlet.

ApplicationInitializer.java
package com.developerstack.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

public class ApplicationInitializer implements WebApplicationInitializer {
	 
    public void onStartup(ServletContext container) throws ServletException {
 
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(BeanConfig.class);
        ctx.setServletContext(container);
        ServletRegistration.Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(ctx));
        servlet.setLoadOnStartup(1);
        servlet.addMapping("/");
    }
}
 Other Interesting Posts
Spring Data JPA Example
Spring Boot Hibernate 5 Example
Spring Hibernate Integration Example
Spring Security Hibernate Example with complete JavaConfig
Spring Boot Actuator Guide
Spring Boot Security Redirect after Login with complete JavaConfig
Securing REST API with Spring Security Basic Authentication
Spring Security Password Encoding using Bcrypt Encoder
Websocket spring Boot Integration without STOMP with complete JavaConfig
Maintaining Spring Session during Websocket Connection
Spring MVC Angularjs Integration with complete JavaConfig
Spring Junit Integration with complete JavaConfig
Spring Ehcache Cacheable Example with complete javaConfig
Spring Boot Spring MVC Example
Spring Boot Thymeleaf Example

Now let us configure our beans. This is the configuration responsible to integrate spring with hibernate.

@Configuration : It indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime.

@EnableWebMvc: Adding this annotation to an @Configuration class imports the Spring MVC configuration from WebMvcConfigurationSupport.

BeanConfig.java
package com.developerstack.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.developerstack")
public class BeanConfig {

	@Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan(new String[]{"com.developerstack.model"});
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
    }

    @Bean
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }

    Properties hibernateProperties() {
        return new Properties() {
            {
                setProperty("hibernate.hbm2ddl.auto", "update");
                setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
                setProperty("hibernate.show_sql", "true");
            }
        };
    }


}

Configuring Hikari Datasource

In the above config file we configured javax.sql.Datasource but there are advanced options too for connection pooling.HikariDatasource is one of the option. It provides many advanced features while configuring our datasource in comparison to other datasources such as connectionTimeout, idleTimeout, maxLifetime, connectionTestQuery, maximumPoolSize and very important one is leakDetectionThreshold.It is as advanced as detecting connection leaks by itself.It is also faster and lighter than other available datasource.Following is the java configuration for HikariDatasource.In production environment you must use this advanced connection pooling.

HikariDatasource Config
@Bean
    public DataSource dataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setMaximumPoolSize(100);
        ds.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
        ds.addDataSourceProperty("url", "jdbc:mysql://localhost:3306/test");
        ds.addDataSourceProperty("user", "root");
        ds.addDataSourceProperty("password", "password");
        ds.addDataSourceProperty("cachePrepStmts", true);
        ds.addDataSourceProperty("prepStmtCacheSize", 250);
        ds.addDataSourceProperty("prepStmtCacheSqlLimit", 2048);
        ds.addDataSourceProperty("useServerPrepStmts", true);
        return ds;
    }

In order to use HikariDataSource, you must include following maven dependency. Checkout the latest version here - Hikari Maven

<dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
             <version>2.7.3</version>
</dependency>

Now let us configure the provision for handling our static contents. This is also configured using java config. Our all static resources are under the folder ui. So we need to tell this to Spring that any static resources request should be looked inside ui folder.

WebConfig.java
package com.developerstack.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

	@Override
	public void addResourceHandlers(final ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/js/**").addResourceLocations("/ui/js/");
		registry.addResourceHandler("/css/**").addResourceLocations("/ui/css/");
		registry.addResourceHandler("/*.html/**").addResourceLocations("/ui/views/");
	}

}

Server Side

Spring Controller

Now let us define our controller. This controller will map the requests coming from angular service. Here we have 2 mappings to validate the user credentials and to load the user details.

UserController.java
package com.developerstack.controller;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.developerstack.model.UserDetails;
import com.developerstack.service.UserService;
import com.google.gson.Gson;

@Controller
public class UserController {
	
	@Autowired
	private UserService userService;
	
	@RequestMapping(value = "/validate", method = RequestMethod.POST)
	public ResponseEntity validate(@RequestBody String userString, HttpServletRequest request) {
        Map user = new Gson().fromJson(userString, Map.class);
		userService.validateUser(user, request);
		return new ResponseEntity(HttpStatus.OK);
	}
	
	@RequestMapping(value = "/details", method = RequestMethod.GET)
	public ResponseEntity> userDetails() {
        
		List userDetails = userService.getUserDetails();
		return new ResponseEntity>(userDetails, HttpStatus.OK);
	}

}

Hibernate Entity

Following is the entity class. The class is annotated as hibernate entity.

UserDetails.java
package com.developerstack.model;

@Entity
@Table
public class UserDetails {
	
	@Id
	@Column
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;
	@Column
	private String firstName;
	@Column
	private String lastName;
	@Column
	private String email;
	@Column
	private String password;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = 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 String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

}

Let us define our service. It has simple logic to validate the user from DB and return the userdetails.

UserServiceImpl.java
package com.developerstack.service.impl;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Service;

import com.developerstack.model.UserDetails;
import com.developerstack.service.UserService;

@Service
public class UserServiceImpl implements UserService {

	@Autowired
	private UserDao userDao;

	public void validateUser(Map user, HttpServletRequest request) {
		String userName = user.get("email");
		String password = user.get("password");
		UserDetails userDetails = userDao.findUserByEmail(email);
		if(userDetails == null || !userDetails.getPassword().equals(password)) {
			throw new RuntimeException("Invalid credentials.");
		}
		return userDetails;
		}
	}

	public List getUserDetails() {
		return userDao.getUserDetails();
	}

}

Let us define the dao.

UserDaoImpl.java
package com.developerstack.dao.impl;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.developerstack.dao.UserDao;
import com.developerstack.model.UserDetails;

@Component
public class UserDaoImpl implements UserDao {
	
	@Autowired
	private SessionFactory sessionFactory;
	
	public UserDetails findUserByEmail(String email) {
		UserDetails userDetails = null;
		Criteria criteria = sessionFactory.openSession().createCriteria(UserDetails.class);
		criteria.add(Restrictions.eq("email", email));
		List entityList = criteria.list();
		if(!entityList.isEmpty()) {
			userDetails = entityList.get(0);
		}
		return userDetails;
	}

	public List getUserDetails() {
		Criteria criteria = sessionFactory.openSession().createCriteria(UserDetails.class);
		return criteria.list();
	}

}

Sample Insert Statement

Following are some sample DML. We can use any one of the pair to login.

create table UserDetails (id integer not null auto_increment, email varchar(255), firstName varchar(255), lastName varchar(255), password varchar(255), primary key (id)) ENGINE=InnoDB;

INSERT INTO userdetails(email,firstName,lastName,password) VALUES ('admin@admin.com','admin','admin','admin');

INSERT INTO userdetails(email,firstName,lastName,password) VALUES ('john@gmail.com','john','doe','johndoe');

INSERT INTO userdetails(email,firstName,lastName,password) VALUES ('sham@yahoo.com','sham','tis','shamtis');

Client Side Code

Client side codes are exactly same as previous post of spring - angular integration example.

Run Application

1. Deploy the app to tomcat 2. Hit the url - http://localhost:8080/spring-hibernate-integration/index.html. Following screen will appear. spring-hibernate-login-form 3. Now enter the userId and password as admin@admin.com and admin. 4. Once validated following screen will appear.

spring-hibernate-integration-dashboard

Conclusion

I hope this article served you that you were looking for. If you have anything that you want to add or share then please share it below in the comment section.

Download the source

Share

If You Appreciate This, You Can Consider:

We are thankful for your never ending support.

About The Author

author-image
A technology savvy professional with an exceptional capacity to analyze, solve problems and multi-task. Technical expertise in highly scalable distributed systems, self-healing systems, and service-oriented architecture. Technical Skills: Java/J2EE, Spring, Hibernate, Reactive Programming, Microservices, Hystrix, Rest APIs, Java 8, Kafka, Kibana, Elasticsearch, etc.

Further Reading on Spring MVC