Spring Boot JpaRepository tutorial
last modified July 6, 2020
SpringBoot JpaRepository tutorial shows how to use JpaRepository to manage data in a Spring Boot application.
Spring is a popular Java application framework. Spring Boot is an effort to create stand-alone, production-grade Spring based applications with minimal effort.
Spring Data
Spring Data is Spring-based programming model for data access. It reduces the amount of code needed for working with databases and datastores. It consists of several modules. The Spring Data JPA simplifies the development of Spring applications that use JPA technology.
With Spring Data, we define a repository interface for each domain entity in
the application. A repository contains methods for performing CRUD operations,
sorting and paginating data. @Repository
is a marker annotation, which
indicates that the underlying interface is a repository. A repository is created
by extending specific repository interfaces, such as CrudRepository
,
PagingAndSortingRepository
, or JpaRepository
.
Spring Data has advanced integration with Spring MVC controllers and provides dynamic query derivation from repository method names.
JpaRepository
JpaRepository
is JPA specific extension of Repository
.
It contains the full API of CrudRepository
and PagingAndSortingRepository
.
So it contains API for basic CRUD operations and also API for pagination and sorting.
Spring Boot JpaRepository example
The following Spring Boot application manages a City
entity with JpaRepository
.
The data is saved in H2 database. The application is a console program.
pom.xml src ├───main │ ├───java │ │ └───com │ │ └───zetcode │ │ │ Application.java │ │ │ MyRunner.java │ │ ├───model │ │ │ City.java │ │ └───repository │ │ CityRepository.java │ └───resources │ application.properties └───test └───java
This is the project structure.
<?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.zetcode</groupId> <artifactId>springbootjparepository</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
This is the Maven build file. The spring-boot-starter-data-jpa
is
a starter for using Spring Data JPA with Hibernate.
spring.main.banner-mode=off logging.pattern.console=%clr(%d{yy-MM-dd E HH:mm:ss.SSS}){blue} %clr(%-5p) %clr(%logger{0}){blue} %clr(%m){faint}%n
The application.properties
is the main Spring Boot configuration file.
With the spring.main.banner-mode
property we turn off the Spring banner. The
logging.pattern.console
defines the log pattern for the console.
package com.zetcode.model; import java.util.Objects; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "cities") public class City { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; private int population; public City() { } public City(String name, int population) { this.name = name; this.population = population; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPopulation() { return population; } public void setPopulation(int population) { this.population = population; } @Override public int hashCode() { int hash = 7; hash = 79 * hash + Objects.hashCode(this.id); hash = 79 * hash + Objects.hashCode(this.name); hash = 79 * hash + this.population; return hash; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final City other = (City) obj; if (this.population != other.population) { return false; } if (!Objects.equals(this.name, other.name)) { return false; } return Objects.equals(this.id, other.id); } @Override public String toString() { var builder = new StringBuilder(); builder.append("City{id=").append(id).append(", name=") .append(name).append(", population=") .append(population).append("}"); return builder.toString(); } }
This is the City
entity. It contains the following
attributes: id
, name
, and population
.
package com.zetcode.repository; import com.zetcode.model.City; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface CityRepository extends JpaRepository<City, Long> { }
The CityRepository
extends from the JpaRepository
.
It provides the type of the entity and of its primary key.
package com.zetcode; import com.zetcode.model.City; import com.zetcode.repository.CityRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Component; @Component public class MyRunner implements CommandLineRunner { private static final Logger logger = LoggerFactory.getLogger(MyRunner.class); @Autowired private CityRepository cityRepository; @Override public void run(String... args) throws Exception { cityRepository.save(new City("Bratislava", 432000)); cityRepository.save(new City("Budapest", 1759000)); cityRepository.save(new City("Prague", 1280000)); cityRepository.save(new City("Warsaw", 1748000)); cityRepository.save(new City("Los Angeles", 3971000)); cityRepository.save(new City("New York", 8550000)); cityRepository.save(new City("Edinburgh", 464000)); logger.info("# of cities: {}", cityRepository.count()); logger.info("All cities unsorted:"); var cities = cityRepository.findAll(); logger.info("{}", cities); logger.info("------------------------"); logger.info("All cities sorted by name in descending order"); var sortedCities = cityRepository.findAll(Sort.by(Sort.Direction.DESC, "name")); logger.info("{}", sortedCities); logger.info("------------------------"); logger.info("Deleting all cities"); cityRepository.deleteAllInBatch(); logger.info("# of cities: {}", cityRepository.count()); } }
In the MyRunner
, we use various methods of the JpaRepository
.
@Autowired private CityRepository cityRepository;
We inject the CityRepository
into the cityRepository
field.
cityRepository.save(new City("Bratislava", 432000));
A new city is inserted with save()
.
logger.info("# of cities: {}", cityRepository.count());
We count the number of cities with count()
.
logger.info("All cities unsorted:"); var cities = cityRepository.findAll(); logger.info("{}", cities);
With findAll()
, we get all cities.
logger.info("All cities sorted by name in descending order"); var sortedCities = cityRepository.findAll(Sort.by(Sort.Direction.DESC, "name")); logger.info("{}", sortedCities);
By passing a Sort
object to the findAll()
method, we
get all cities sorted by names in descending order.
logger.info("Deleting all cities"); cityRepository.deleteAllInBatch();
We delete all cities in a batch with deleteAllInBatch()
.
package com.zetcode; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
The Application
sets up the Spring Boot application.
... 19-06-25 Tue 12:47:14.593 INFO MyRunner # of cities: 7 19-06-25 Tue 12:47:14.593 INFO MyRunner All cities unsorted: 19-06-25 Tue 12:47:14.652 INFO MyRunner [City{id=1, name=Bratislava, population=432000}, City{id=2, name=Budapest, population=1759000}, City{id=3, name=Prague, population=1280000}, City{id=4, name=Warsaw, population=1748000}, City{id=5, name=Los Angeles, population=3971000}, City{id=6, name=New York, population=8550000}, City{id=7, name=Edinburgh, population=464000}] 19-06-25 Tue 12:47:14.652 INFO MyRunner ------------------------ 19-06-25 Tue 12:47:14.652 INFO MyRunner All cities sorted by name in descending order 19-06-25 Tue 12:47:14.667 INFO MyRunner [City{id=4, name=Warsaw, population=1748000}, City{id=3, name=Prague, population=1280000}, City{id=6, name=New York, population=8550000}, City{id=5, name=Los Angeles, population=3971000}, City{id=7, name=Edinburgh, population=464000}, City{id=2, name=Budapest, population=1759000}, City{id=1, name=Bratislava, population=432000}] 19-06-25 Tue 12:47:14.668 INFO MyRunner ------------------------ 19-06-25 Tue 12:47:14.668 INFO MyRunner Deleting all cities 19-06-25 Tue 12:47:14.681 INFO MyRunner # of cities: 0 ...
This is a sample output.
In this tutorial, we have managed our application data with JpaRepository
.