Monday, March 20, 2023

Spring Boot + Hibernate Tutorial and Example for Java Developers

Hello guys, if you want to learn how to use Spring Boot and Hibernate together in a Java application and look for examples and tutorials then you have come to the right place. In the past, I have shared how to use Spring Boot with MyBatis and Spring Boot + Redis example and In this article on Spring Boot, we will discuss how to integrate Spring Boot with Hibernate. We will build a simple Spring Boot application and use Hibernate to store the data. So first, let's look at what is Hibernate in Java? Hibernate framework provides an abstraction layer which means programmers need not worry about implementation. Hibernate will implement different modules for developers internally like writing queries to perform CRUD operations on the database and establishing connections to different kinds of databases. This is a Java-based solution for object-relational mapping.

The programming technique of object-relational mapping, or ORM, is used to map application domain model objects to relational database tables. Hibernate is a Java-based object-relational mapping (ORM) technology that allows you to map application domain objects to relational database tables and vice versa.

Spring Boot + Hibernate Example for Java Developrs


1. Spring Boot with Hibernate

So first, create a spring boot application with the following options.
  
   1. Spring Initializer
  
   2. Use IDE
  
   3. Use Spring Boot CLI tool

Here, we are using the spring boot CLI and as a part of this, we added the Web, JPA, and MySql dependencies to our application. To start the project, go to the spring boot initializer from https://start.spring.io/ and add the above dependencies. This is shown in the below picture.



This is what your pom.xml will look like after the creation of the project.

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>studentproject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>studentproject</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
 

All maven settings required for each spring project are provided by spring-boot-starter-parentWe also need to include spring-boot-starter-web and spring-boot-starter-data-JPA to run this application with hibernate because we are constructing a web application. 

In this example, we are using MySQL, In case you want to use the h2 database, you can add the h2 dependencies to the pom.xml file without using the Mysql dependencies.




2. Hibernate Configuration

To configure the hibernate in our project, we use the HibernateConfiguration.java class. It is given in the below example code.

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
public class HibernateConfiguration {
@Value("${db.driver}")
private String DRIVER;

@Value("${db.password}")
private String PASSWORD;

@Value("${db.url}")
private String URL;

@Value("${db.username}")
private String USERNAME;

@Value("${hibernate.dialect}")
private String DIALECT;

@Value("${hibernate.show_sql}")
private String SHOW_SQL;

@Value("${hibernate.hbm2ddl.auto}")
private String HBM2DDL_AUTO;

@Value("${entitymanager.packagesToScan}")
private String PACKAGES_TO_SCAN;

@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DRIVER);
dataSource.setUrl(URL);
dataSource.setUsername(USERNAME);
dataSource.setPassword(PASSWORD);
return dataSource;
}

@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(PACKAGES_TO_SCAN);
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", DIALECT);
hibernateProperties.put("hibernate.show_sql", SHOW_SQL);
hibernateProperties.put("hibernate.hbm2ddl.auto", HBM2DDL_AUTO);
sessionFactory.setHibernateProperties(hibernateProperties);

return sessionFactory;
}

@Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
}

In the above, you can see that we have used the @Bean and @Configuration annotations. These annotations are used to define beans in spring. @Value annotation is used to inject variables from properties files.

So let's have a look into our application.properties file in the spring boot application.
server.port=8080

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost/starbucks?createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect




2. Model Class

Create a model class named Student.java. This is the file that is using @Entity annotation and for this class, you will have the corresponding table in the database.

The model class which used in this application is given below.

package com.student.crudapp.model;

import javax.persistence.*;

@Entity
@Table(name = "STUDENT")
public class Student {

@Column(name = "id")
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;

@NotBlank(message = "Name is mandatory")
@Column(name = "name")
private String name;

@NotBlank(message = "Email is mandatory")
@Column(name = "email")
private String email;

@NotBlank(message = "Grade is mandatory")
@Column(name = "grade")
private String grade;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getGrade() {
return grade;
}

public void setGrade(String grade) {
this.grade = grade;
}

@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", grade='" + grade + '\'' +
'}';
}
}


When creating a persistent pojo class, @Entity is utilized. You will have a comparable table in the database for this Java class. @Column is used to link annotated attributes to their respective table columns.
We have now a basic entity, which H2 can create a table from. Restarting the application and checking H2 console, a new table called Book will be created.




3. Repository Layer

Add the StudentRepository.java class to the application in order to handle the SQL data.

package com.student.crudapp.repository;

import com.student.crudapp.model.Student;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface StudentRepository extends JpaRepository<Student, Integer> {

List<Student> findAll();
Student findById(int id);
int deleteById(int id);


}

The spring data JPA will generate implementation code for the most common CRUD operations and you do not need to stick with customized queries



4. Service Class

Create a service class named StudentService.java and attached the following code there. This is used to get the 
package service;

import com.student.crudapp.model.Student;
import com.student.crudapp.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class StudentService {

@Autowired
StudentRepository studentRepository;

//Get all the students
public List<Student> getAllStudents() {
List<Student> students = studentRepository.findAll();
return students;
}

//display one student by id
public Student getStudentById(int id) {
return studentRepository.findById(id);
}

//save student in database
public void saveStudent(Student student) {
try{
studentRepository.save(student);
}
catch(Exception e){
e.printStackTrace();
}
}

//delete stuednt by id
public void deleteStudent(int id) {
try{
studentRepository.deleteById(id);
}catch(Exception e){
e.printStackTrace();
}
}

}



      
      
      

5. Controller Class 

This is the class which is dealing with RESTful APIs for CRUD operations.
package com.student.crudapp.controller;

import com.student.crudapp.model.Student;
import com.student.crudapp.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Controller
public class StudentController {

@Autowired
StudentRepository studentRepository;

//check the api's working correctly api
@RequestMapping(value="/ping", method=RequestMethod.GET)
@ResponseBody
public String healthCheck() {
return "This is working well";
}


@RequestMapping(value="/students", method=RequestMethod.GET)
@ResponseBody
public List<Student> getAllStudents() {
return studentRepository.findAll();
}

@RequestMapping(value="/student", method=RequestMethod.POST)
@ResponseBody
public Student addStudent(Student student) {
return studentRepository.save(student);
}

@RequestMapping(value="/findstudent", method = RequestMethod.GET)
@ResponseBody
public Student findStudent(@RequestParam("studentId") int studentId) {
return studentRepository.findById(studentId);
}

@RequestMapping(value= "/updatestudent", method = RequestMethod.GET)
@ResponseBody
public Student updateStudent(@RequestBody Student student){
return studentRepository.save(student);
}

@RequestMapping(value="/deletestudent", method = RequestMethod.GET)
@ResponseBody
public int deleteStudent(@RequestParam("studentId") int studentId) {
return studentRepository.deleteById(studentId);
}
}

Here, the @Controller annotation is used to expose the RESTful APIs. The rest controller still takes advantage of the spring's dependency injection.

Hibernate used in Spring

As you see in the above model class, Student.java we used the tables names in upper case letters. As we already know, by default hibernate will generate the names of the tables in lowercase letters.

@Entity
@Table(name = "STUDENT")
public class Student {
    //your code here
}

But this will not work unless you setting this property in application.properties file. This will allow you to create your tables names in database in upper case.
spring.jpa.hibernate.naming.physical-strategy
  =org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

When should we use Hibernate along with Spring and also what is the advantage?

When you use spring, you use IOC to resolve the 'plumbing' code that connects the various application layers. As a result, Spring functions as a middleware, allowing any other compatible technology to access your data layer through a context without requiring explicit data dependencies. 

The hibernate configuration will be affected by changes in your database, but you can specify how many changes you want to translate into your application. I wouldn't recommend these frameworks for really high performance/esoteric applications because they were built with enterprise application requirements and design principles in mind.
Two benefits that you get from using hibernate with spring,
    1. Spring provides a transaction abstraction to make transaction management easier and also provides declarative transactions. Furthermore, spring will handle hibernate's sessions for you.
    2. Spring also provides a hibernate helper class (HibernateDaoSupport). It's much easier to write DAO implementation with it.


Conclusion

That's all about how to use Spring Boot and Hibernate together in a Java application. In this article, we discussed how to integrate hibernate with spring boots. We used Mysql as the database. Hope you understand how to create your application using the spring hibernate, see you in the next tutorial. Until then bye!

Other Spring Framework articles you may like to explore 


    Thanks for reading this article so far. If you find this Spring Boot and Hiberante example tutorial useful, please share them with your friends and colleagues. If you have any questions or feedback, then please drop a note.

    P. S. - If you are new to Spring and Hibernate and keen to learn both Spring and Hibernate in depth, then you can also check out this list of best Spring and Hibernate online courses for Java developers. You will save a lot of time. 

    1 comment:

    1. it's spring data. not hibernate. please change title of the article.

      ReplyDelete