Spring Data JPA
Spring Data JPA is a popular Spring Framework projects, and simplifies creating JPA-based repositories by reducing the boilerplate code required to implement data access layers. It provides enhanced support for JPA-based data access using Spring annotation driven programming.
Spring Data JPA provides out-of-the-box support for PostgreSQL-compliant databases. This includes auto-reconfiguration support for creating the data source objects based on the database driver in the classpath. YugabyteDB provides complete support for Spring Data JPA using the PostgreSQL dialect. Spring Data JPA repositories can be used to read and write data to YugabyteDB clusters.
This document describes the fundamentals of using Spring Data JPA with YugabyteDB to create Spring Boot applications.
Quick start
Learn how to establish a connection to YugabyteDB database and begin basic CRUD operations using the steps in Java ORM example application.
Project dependencies
Spring Data JPA can be used with both YugabyteDB JDBC driver and the upstream PostgreSQL JDBC driver.
Maven dependency
Add the following dependencies for Spring Data JPA with YugabyteDB JDBC Driver.
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>com.yugabyte</groupId>
<artifactId>jdbc-yugabytedb</artifactId>
<version>42.3.4</version>
</dependency>
<dependencies>
If you're planning to use the PostgreSQL JDBC driver, use the following dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.14</version>
</dependency>
<dependencies>
Fundamentals
Learn how to perform common tasks required for developing Spring Boot applications using Spring Data JPA with YugabyteDB YSQL API.
Connect to YugabyteDB Database using Spring Data JPA
The Spring Data JPA project provides number of spring.datasource.*
properties that can be customized to configure the data source and transaction behavior of Spring Boot applications.
Configure the Spring Boot application to connect to a YugabyteDB Cluster using the following properties in the application.properties
file:
YugabyteDB JDBC driver
spring property | Description | Value |
---|---|---|
spring.datasource.url | JDBC URL | jdbc:yugabytedb://127.0.0.1:5433/yugabyte?load-balance=true |
spring.datasource.username | user for connecting to the database | yugabyte |
spring.datasource.password | password for connecting to the database | yugabyte |
spring.datasource.driver-class-name | JDBC driver classname | com.yugabyte.Driver |
spring.datasource.hikari.minimum-idle | JDBC connection idle timeout | 5 |
spring.datasource.hikari.maximum-pool-size | Maximum number of DB connections in the Pool | 20 |
spring.datasource.hikari.auto-commit | Transaction commit behavior | false |
PostgreSQL JDBC driver
spring property | Description | Value |
---|---|---|
spring.datasource.url | JDBC URL | jdbc:postgresql://localhost:5433/yugabyte |
spring.datasource.username | user for connecting to the database | yugabyte |
spring.datasource.password | password for connecting to the database | yugabyte |
spring.datasource.hikari.minimum-idle | JDBC connection idle timeout | 5 |
spring.datasource.hikari.maximum-pool-size | Maximum number of DB connections in the Pool | 20 |
spring.datasource.hikari.auto-commit | Transaction commit behavior | false |
Create table
Spring Data JPA uses Hibernate ORM for handling creation of the database tables based on the domain objects configured in the Spring Boot application. Java POJOs annotated with @Table
and @Entity
are mapped to the corresponding YugabyteDB table.
For example:
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(columnDefinition = "serial")
private Long userId;
...
This domain object maps to the users
table on the database, which has userId
as the primary key and an auto incrementing type.
Spring Boot applications can be configured to determine whether tables should be created on application startup or not. Add the following property in application.properties
to configure the database table creation behavior.
# Hibernate ddl auto (create, create-drop, validate, update, none).
spring.jpa.hibernate.ddl-auto=create
For production environments, it's good practice to disable database table creation on startup. To prevent table creation on startup, set the property to none
.
Read and write data
Enable JPA repositories
Spring Data JPA repositories provide support for CRUDRepository
, JPARepository
, and PagingAndSortingRepository
. By enabling these repositories, Spring Boot applications get access to data access methods out of the box. For more information, refer to the Spring Data JPA reference documentation.
public interface CrudRepository<T, ID> extends Repository<T, ID> {
<S extends T> S save(S entity);
Optional<T> findById(ID primaryKey);
Iterable<T> findAll();
long count();
void delete(T entity);
boolean existsById(ID primaryKey);
// … more functionality omitted.
}
Spring Boot applications can be configured to enable these repositories by using the following Java configuration class.
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@EnableJpaRepositories
class Config { … }
Insert data
To write data to YugabyteDB, implement the repository for each domain object.
For example:
import org.springframework.data.jpa.repository.JpaRepository;
import com.yugabyte.springdemo.model.User;
public interface UserRepository extends JpaRepository<User, Long> {
}
This repository can then be used to insert data into the Users
table.
@Autowired
private UserRepository userRepository;
...
@PostMapping("/users")
public User createUser(@Valid @RequestBody User user) {
return userRepository.save(user);
}
Query data
To read data in YugabyteDB, use the out-of-the-box query methods exposed by the repositories.
For example:
@Autowired
private UserRepository userRepository;
@PutMapping("/users/{userId}")
public User updateUser(@PathVariable Long userId,
@Valid @RequestBody User userRequest) {
return userRepository.findById(userId)
.map(user -> {
user.setFirstName(userRequest.getFirstName());
user.setLastName(userRequest.getLastName());
user.setEmail(userRequest.getEmail());
return userRepository.save(user);
}).orElseThrow(() -> new ResourceNotFoundException("User not found with id " + userId));
}
Spring Data JPA repositories provide named queries for adding custom queries to repositories and to update the behavior of built-in queries by using the @Query
annotation in the repository implementation.
For example:
import org.springframework.data.jpa.repository.JpaRepository;
import com.yugabyte.springdemo.model.User;
public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);
}
Transaction and isolation levels
YugabyteDB supports transactions for inserting and querying data from the tables. YugabyteDB supports different isolation levels for maintaining strong consistency for concurrent data access.
By default, CRUD methods on a JPA repository are transactional. For read operations, the transaction configuration readOnly
flag is set to true. All others are configured with a plain @Transactional
so that the default transaction configuration applies.
The transaction and isolation level of Spring Boot applications can be configured by setting the following properties in the application.properties
file.
spring.datasource.hikari.transactionIsolation=TRANSACTION_SERIALIZABLE
Compatibility matrix
Spring Data JPA | YugabyteDB Smart Driver | Postgres JDBC Driver |
---|---|---|
2.6.x | 42.3.4 | 42.2.7 or later |
2.5.x | 42.3.4 | 42.2.7 or later |