Spring Boot — Accessing Data with JPA Hibernate and PostgreSQL

minelaydin
Analytics Vidhya
Published in
5 min readNov 20, 2020

--

Hello! I will talk about how to create a Spring Boot project using Hibernate and PostgreSQL. First, I want to explain what is ORM, JPA and Hibernate.

ORM (Object Relational Mapping): ORM is a programming tecnique that allows our model classes to match our tables in the relational database. It can be thought of as a bridge between an application and a relational database.

JPA (Java Persistence API): JPA is a specification. It is a collection of classes and methods to persistently store the vast amounts of data into a database. It provides common prototype and functionality to ORM tools. By implementing the same specifiation, all ORM tools (like Hibernate, TopLink..) follows the common standarts.

Hibernate: Hibernate is an implementation of JPA. It is an ORM (Object Relational Mapping) solution for Java environments. It follows the common standarts provided by the JPA.

Soon, thanks to Hibernate, we will do database operations without writing long SQL queries.

Now let’s create a simple application named Covid Information System. Add patient to PostgreSQL database using hibernate, list all patients and update the status of patients.

You can find full code here: https://github.com/minnela/SpringBootHibernateJPA

First you should set up PostgreSQL on your PC. You can download it here: https://www.postgresql.org/download/

Project Structure will be like this:

Here is pom.xml file:

<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>covidInformationSystem</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<java.version>1.8</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-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.17</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

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


</project>

Now in application.properties file, we will connect PostgreSQL and configure hibernate and jpa:

server.port = 4567
spring.jpa.database=POSTGRESQL
spring.datasource.platform= postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=admin
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation= true

MODEL

Let’s create our Entity class. @Entity annotation will let Spring Boot to create our Entity Table. We will create Person class, and the person table will be automatically added in postgreSQL.

@Entity
public class Person {

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

@Column(name="firstname")
private String name;

@Column(name= "surname")
private String surname;

@Column(name="age")
private int age;

@Column(name="covidinfo")
private String covidInfo;

Add constructor, getter and setter methods in Person class.

REPOSITORY

Now it is time to create a Person Repository. This repository holds each person to be added to the system. We will create a PersonRepository interface and it will extend JPA Repository class. JPA repository has many functions that we can use for database operations.

@Repository
public interface PersonRepository extends JpaRepository<Person, Integer> {
}

Service

Service is a layer that we create to encapsulate the business logic in the Controller and it is a bridge between the Controller and the Model.

Let’s create PersonService:

public interface PersonService {
void addPerson(Person person);
List<Person> getAllPatients();
Person getPersonById(int id);
void updatePersonCovidInfo(int id);
void deletePersonById(int id);

}

And let’s create it’s implementation PersonServiceImpl. We create an object of PersonRepository. To add a person to database, it will be enough to write personRepository.save(person). As you see, we do not use a long SQL query to save a person:

@Service
public class PersonServiceImpl implements PersonService{

PersonRepository personRepository;

@Autowired
public PersonServiceImpl(PersonRepository personRepository) {
this.personRepository = personRepository;
}

@Override
public void addPerson(Person person) {
personRepository.save(person);
}

@Override
public List<Person> getAllPatients() {
List<Person> peopleList = personRepository.findAll();
return peopleList;
}

@Override
public Person getPersonById(int id) {
return personRepository.getOne(id);
}

Controller

To register a patient to the system we will create a PersonController class and add PersonService methods:

@Controller
public class PersonController {
PersonService personService;

@Autowired
public PersonController(PersonService personService) {
this.personService = personService;
}

@RequestMapping("/register")
public ModelAndView getRegisterPage(){
return new ModelAndView("addUser", "person", new Person());
}
@RequestMapping(value="/register", method= RequestMethod.POST)
public String handleRegisterForm(@Valid @ModelAttribute("person") Person person, BindingResult bindingResult) throws SQLException {
if(bindingResult.hasErrors()){
return "addUser";
}
personService.addPerson(person);

return "redirect:/";
}

@RequestMapping("/patients")
public ModelAndView getUsersPage(){
return new ModelAndView("patients","patients",personService.getAllPatients());
}

Now, we can add our views for some visuality under resources file. After adding view html files, let’s go localhost:4567/register adress:

We can add a patient to the system here and it will be hold in PostgreSQL database. Then we can list all the patients in the database at localhost: 5678/patient.

Now we will add an Update Button for all patients to change their covid status. To do that we will use @Query annotation in PersonRepository class:

@Repository
public interface PersonRepository extends JpaRepository<Person, Integer> {
@Transactional
@Modifying
@Query("update Person p set p.covidInfo = :covidInfo where p.id = :id")
void setCovidInfo(@Param("covidInfo") String covidInfo, @Param("id") int id);

Person findByName(String name);
}

Here we write an update method in JPA Repository. We create a query that updates covid status of patients. Let’s add it into Service, Controller and Patient View:

Service

@Override
public void updatePersonCovidInfo(int id) {
personRepository.setCovidInfo("Negative",id);
}

Controller

Spring Boot html does not allow us to use PUT method so here I use POST method to update covid status of patients:

@RequestMapping(value="/updateCovidInfo/{id}", method= RequestMethod.POST)
public String updateStatus(@PathVariable("id") int id){
personService.updatePersonCovidInfo(id);
return "redirect:/patients";
}

View

<tr th:each="patient : ${patients}">
<td th:text="${patient.name}">Patient name</td>
<td th:text="${patient.surname}">Patient surname</td>
<td th:text="${patient.age}">Patient age</td>
<td th:text="${patient.covidInfo}">Patient covid information</td>
<td>
<form action="#" th:action="@{'/updateCovidInfo/'+${patient.id}}" th:method="post" >
<input type="hidden" name="_method" value="post" />
<button type="submit" id="Approve" name="Approve">Update Covid Info </button>
</form>
</td>

<td>
<form action="#" th:action="@{'/deletePatient/'+${patient.id}}" th:method="post" >
<button type="submit" >Delete Patient </button>
</form>
</td>
</tr>

Thus, I have explained the Spring Boot Hibernate structure to you with a simple project. For more detailed information, you can examine the source codes of the project :

Thank you for reading :)

--

--