Spring Data JPA allows you to build scalable backend applications backed by any relational database. It is a great choice allowing you to speed up your development and and focus on the business logic.
In this article, you are going to learn the following:
What is Sring Data JPA
Connect to real database not in the memory DB
How to map classes to tables
Hibernate entity life cycle
Queries
Paging and sorting
1 to 1 relationships
1 to many relationships
Many to many relationships
Transactions
Here, in this article, you will learn how to this Application Database Design using Spring Data JPA.
What Is Spring Data JPA?
Spring Data JPA is a framework that abstracts all of the complexity needed for you to interact with your databases.
JPA (Java Persistent API) is the sun specification for persisting objects in the enterprise application. It is currently used as a replacement for complex entity beans. It is a specification for accessing persisting and managing data between Java objects.
Hibernate is one implementation of the Spring Data JPA interface. It tackles any Java object.
Spring Data JPA gives a lot of queries and we can access our database without having to write any single line of SQL and that happens through repositories. It makes the relationship between Spring Data JPA and Spring Boot much easier without having to configure a lot of things.
For this tutorial, I’m gonna be using IntellijIDEA. There are two versions, the community one which is free, and the ultimate edition. For this I am using the ultimate edition since I am going to do lots of database work, it gives us the database functionality right within IntelliJ. By so doing, we can see the tables, and indexes, and can perform queries.
Behold that the ultimate edition is not free, but it has a free trial for a month. If you don’t have IntelliJ download it here.
You can start your app from the cloned repository or start from scratch. This article assumes you already know how to clone or start a Spring Boot application. Configuration is the most important part, so I’m gonna show you how to do it here.
To start the application, open the application properties, and add the following configurations:
spring.application.name=demo
spring.datasource.url=jdbc:postgresql://localhost:5432/mercy
spring.datasource.username=
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgresSQLDialect
spring.jpa.properties.hibernate.format_sql=true
Demo is the name of the application.
Following the connection URL for our database username and password. I am using a Mac so I don’t have to specify the username and password, but if you are on Windows, you have to specify.
The create-drop
means create a schema and before the app shuts down drop everything. Set show-sql
to true
so that you can see the SQL statements that Hibernate
will be generated. Specify the dialect and also configure SQL
to be formatted.
You can use commands to create databases like CREATE DATABASE anesu;
this will create a new database called anesu
. If successful, you will see CREATE DATABASE
. After creating the database, you can connect to it using: c anesu
You can also connect to the database inside the IntellijIDEA by clicking the database icon on the top right corner, clicking the plus button, hovering over the data source, and it will display data sources you can use to connect to your database. Choose the one of your choice, but in this article, we will be using PostgreSQL.
Set Up the pom.xml
Then, open pom.xml, and add these 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.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
Define Data Model
package com.bezkoder.spring.jpa.postgresql.model;
// import javax.persistence.*; // for Spring Boot 2
import jakarta.persistence.*; // for Spring Boot 3
@Entity
@Table(name = "tutorials")
public class Tutorial {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "title")
private String title;
@Column(name = "description")
private String description;
@Column(name = "published")
private boolean published;
public Tutorial() {
}
public Tutorial(String title, String description, boolean published) {
this.title = title;
this.description = description;
this.published = published;
}
public long getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean isPublished() {
return published;
}
public void setPublished(boolean isPublished) {
this.published = isPublished;
}
@Override
public String toString() {
return "Tutorial [id=" + id + ", title=" + title + ", desc=" + description + ", published=" + published + "]";
}
}
– @Entity
annotation indicates that the class is a persistent Java class.
–@Table
annotation provides the table that maps this entity.
–@Id
annotation is for the primary key.
–@GeneratedValue
annotation is used to define the generation strategy for the primary key. GenerationType.AUTO
means Auto Increment field.
–@Column
annotation is used to define the column in the database that maps the annotated field.
Create Repository Interface
Let’s create a repository to interact with Tutorials from the database.
In the repository package, create TutorialRepository
an interface that extends JpaRepository
.
repository/TutorialRepository.java
package com.bezkoder.spring.jpa.postgresql.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import com.bezkoder.spring.jpa.postgresql.model.Tutorial;
public interface TutorialRepository extends JpaRepository<Tutorial, Long> {
List<Tutorial> findByPublished(boolean published);
List<Tutorial> findByTitleContaining(String title);
}
Now, we can use JpaRepository’s methods: save()
, findOne()
, findById()
, findAll()
, count()
, delete()
, deleteById()
… without implementing these methods.
We also define custom finder methods:
–findByPublished()
: returns all Tutorials with published
having value as input published
.
–findByTitleContaining()
: returns all Tutorials whose title contains input title
.
The implementation is plugged in by Spring Data JPA automatically.
More Derived queries at:
JPA Repository query example in Spring Boot
Custom query with @Query
annotation:
Spring JPA @Query example: Custom query in Spring Boot
You can modify this Repository:
– to work with Pagination, the instructions can be found at:
Spring Boot Pagination & Filter example | Spring JPA, Pageable
– or to sort/order by multiple fields with the tutorial:
Spring Data JPA Sort/Order by multiple Columns | Spring Boot
You also find a way to write a Unit Test for this JPA Repository at:
Spring Boot Unit Test for JPA Repository with @DataJpaTest
Or: Spring Boot Unit Test for Rest Controller
Unfortunately for this, I am not going to give out all code files considering this post is for people who know how to use Spring Boot.
Create Spring Rest APIs Controller
Finally, we create a controller that provides APIs for creating, retrieving, updating, deleting, and finding Tutorials.