This article teaches you how to quickly integrate and use Spring Data Jpa in your SpringBoot applications.

This tutorial uses MYSQL as an example. If you use other databases, e.g. PostgreSQL, then you need to modify the jdbc driver, database, dialect and other related configurations.

Practice

Required Maven dependencies

The required dependencies are as follows.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <scope>provided</scope>
</dependency>

application.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
spring:
  # Configuration of the datasource
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
    username: root
    password: root  
  
  # Configuration of spring data jpa
  data:
    jpa:
      # dialect
      database-platform: org.hibernate.dialect.MySQL8Dialect
      # Printing SQL Logs
      show-sql: true
      # Do not register OpenEntityManagerInViewInterceptor
      open-in-view: false

The configuration of the data source is necessary. For more configuration of spring data jpa you can refer to the following configuration classes or the official documentation.

Creating entity classes

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package io.springboot.demo.entity;

import java.math.BigDecimal;
import java.time.LocalDateTime;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.With;

@Data
@AllArgsConstructor
@NoArgsConstructor
@With
@Builder

@Entity
@Table(name = "user")
public class User {

    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.IDENTITY) // Use auto-incrementing ID
    private Integer id;
    @Column
    private String name;
    @Column
    private BigDecimal balance;
    @Column
    private Boolean enabled;
    @Column
    private LocalDateTime createAt;
    @Column
    private LocalDateTime updateAt;
}

There is also support for defining unique constraints, index columns, etc. through annotations, which can be used to automatically create data tables. If you are interested you can check the official documentation.

Creating Repository Interfaces

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package io.springboot.demo.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;

import io.springboot.demo.entity.User;


@Repository
public interface UserRepository extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User> {

}

Inherit the JpaRepository and JpaSpecificationExecutor interfaces, which can give us more convenient methods.

Annotation Drivers

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package io.springboot.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@EnableJpaRepositories(basePackages = { "io.springboot.demo.repository" })
@EntityScan(basePackages = { "io.springboot.demo.entity" })
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

The paths to the Repository and Entity packages are specified via the @EnableJpaRepositories and @EntityScan annotations, respectively.

Testing

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package io.springboot.test;


import java.math.BigDecimal;
import java.time.LocalDateTime;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import io.springboot.demo.DemoApplication;
import io.springboot.demo.entity.User;
import io.springboot.demo.repository.UserRepository;
import lombok.extern.slf4j.Slf4j;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@Slf4j
public class DemoApplicationTest {

    @Autowired
    UserRepository userRepository;

    @Test
    @Transactional
    @Rollback(false)
    public void test() {
        
        User user = this.userRepository.save(User.builder()
                                                .name("JPA")
                                                .balance(new BigDecimal("15.88"))
                                                .enabled(true)
                                                .createAt(LocalDateTime.now())
                                                .updateAt(LocalDateTime.now())
                                                .build()
                                            );
        
        log.info("saved user: {}", user);
    }
}

The output logs:

1
2
3
2022-06-08 10:09:10.790 DEBUG 8008 --- [           main] org.hibernate.SQL                        : insert into user (balance, create_at, enabled, name, update_at) values (?, ?, ?, ?, ?)
...
2022-06-08 10:09:10.831  INFO 8008 --- [           main] io.springboot.test.DemoApplicationTest   : saved user: User(id=15, name=JPA, balance=15.88, enabled=true, createAt=2022-06-08T10:09:10.756166100, updateAt=2022-06-08T10:09:10.756166100)

As you can see, the data was successfully saved.

Summary

The steps to use Spring Data Jpa in Spring Boot can be summarized as follows:

  1. Add the required dependencies.
  2. Configure the database and other configuration items in the configuration file.
  3. Define the entity classes.
  4. Define the Repository interface.
  5. Add the annotation driver to specify the package path where the Repository and entity classes are located.
  6. The Repository can be used by injection.

Finally, let’s query the data we just inserted.

1
2
3
4
5
6
7
mysql> select * from user;
+----+---------+---------------------+---------+------+---------------------+
| id | balance | create_at           | enabled | name | update_at           |
+----+---------+---------------------+---------+------+---------------------+
| 15 |   15.88 | 2022-06-08 10:09:11 |       1 | JPA  | 2022-06-08 10:09:11 |
+----+---------+---------------------+---------+------+---------------------+
1 row in set (0.00 sec)