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
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.javapackage 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.javapackage 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.javapackage 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.javapackage 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) { Mapuser = 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.javapackage 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.javapackage 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(Mapuser, 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.javapackage 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)); ListentityList = 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. 3. Now enter the userId and password as admin@admin.com and admin. 4. Once validated following screen will appear.
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.