Spring Boot JpaRepository Example
Hello readers let us delve into understanding the Spring Data JPA module.
1. JpaRepository interface
Spring Data JPA provides a powerful abstraction over the data access layer, allowing developers to interact with the database using repository interfaces. The JpaRepository
interface in Spring Data JPA provides CRUD operations and more for the entity class that is being managed. It extends PagingAndSortingRepository
which in turn extends CrudRepository
. This inheritance chain provides a rich set of methods for interacting with the database.
1.1 Advantages and Disadvantages of Spring Data JPA
1.1.1 Advantages of Spring Data
- Reduced Boilerplate Code: Spring Data JPA significantly reduces the amount of boilerplate code needed to interact with the database by providing ready-to-use implementations for common CRUD operations.
- Built-in Query Methods: It offers a variety of built-in query methods, allowing developers to perform common database operations without writing custom queries.
- Custom Query Support: Developers can define custom query methods using the method naming conventions or the @Query annotation to write JPQL or native SQL queries.
- Integration with Spring Framework: Spring Data JPA integrates seamlessly with the Spring ecosystem, providing consistent and easy-to-use data access features within a Spring application.
- Pagination and Sorting: It provides out-of-the-box support for pagination and sorting, making it easier to handle large datasets efficiently.
- Abstraction Layer: Spring Data JPA acts as an abstraction layer over JPA, which helps in reducing the complexity of JPA’s verbose configurations and APIs.
- Database Agnosticism: The use of JPA annotations makes the codebase database-agnostic, allowing easier switching between different databases with minimal changes.
- Auditing and Versioning: It supports auditing and versioning out-of-the-box, which is useful for tracking changes and maintaining historical data.
1.1.2 Disadvantages of Spring Data
- Learning Curve: Despite simplifying data access, Spring Data JPA still requires a good understanding of JPA and Hibernate concepts, which can have a steep learning curve for beginners.
- Potential Overhead: The abstraction layer adds some overhead, which might affect performance in highly optimized or resource-constrained environments.
- Limited Control: Using Spring Data JPA’s abstracted methods can sometimes limit fine-grained control over the underlying SQL, which might be necessary for complex queries or optimizations.
- Complex Queries: For highly complex queries, developers might still need to resort to native SQL queries, which can be less readable and harder to maintain.
- Debugging Difficulty: Debugging can become more challenging due to the abstraction layers, as understanding the root cause of issues might require digging deeper into the framework’s internals.
- Dependency on Spring Framework: Tight coupling with the Spring ecosystem means that migrating away from Spring can be difficult and require significant refactoring.
- Configuration Management: In large projects with complex configurations, managing and tuning Spring Data JPA settings can become cumbersome.
2. Setting up a database on Docker
Usually, setting up the database is a tedious step but with Docker, it is a simple process. You can watch the video available at this link to understand the Docker installation on Windows OS. Once done open the terminal and trigger the below command to set and run postgresql.
-- Remember to change the password -- docker run -d -p 5432:5432 -e POSTGRES_PASSWORD= --name postgres postgres -- command to stop the Postgres docker container -- docker stop postgres -- command to remove the Postgres docker container -- docker rm postgres
Remember to enter the password of your choice. If everything goes well the postgresql database server will be up and running on a port number – 5432
and you can connect with the Dbeaver GUI tool to connect to the server.
2.1 Setting up pre-requisite data
To proceed further with the tutorial we will set up the required mock data in the postgresql.
drop database mydatabase; create database mydatabase; drop table product; create table product(id serial primary key, name varchar(100), category varchar(100)); select * from product; insert into product (name, category) values ('Tablet1', 'Electronics'), ('Tablet1', 'Electronics'), ('Smartphone', 'Electronics'), ('Desk', 'Furniture');
3. Code Example
3.1 Dependencies
Add the following dependencies to your pom.xml
file or if you have created a spring project from start.spring.io this won’t be necessary as the file will be automatically populated with the dependencies information.
<!--for jpa--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!--database--> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> </dependency>
3.2 Configure application and database properties
Add the following properties to the application.properties
file present in the resources
folder.
# application name spring.application.name=springjpademo # database properties spring.datasource.url=jdbc:postgresql://localhost:5432/mydatabase spring.datasource.username=postgres spring.datasource.password=somepostgrespassword # application properties server.port=9090 spring.main.banner-mode=off spring.main.log-startup-info=false
3.3 Creating the Model Classes
Create a Product entity class to internal with the JpaRepository
interface.
@Entity @Table public class Product { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; private String category; // toString, Getters, and Setters methods }
3.4 Creating the Data Interaction Layer
Create the product repository interface to interact with the product entity for fetching the data from the table using the JpaRepository interface.
@Repository public interface ProductRepository extends JpaRepository<Product, Long> { @Query("SELECT p FROM Product p WHERE p.name like %:name%") List<Product> findByNameLike(@Param("name") String name); }
The given code defines a Spring data interface that extends JpaRepository<Product, Long>
providing crud operations ability. Within this interface, a custom query method findByNameLike
annotated with the @Query
annotation is defined to select products from the Product
entity where the product name matches a given using the SQL LIKE operator. Similarly, you can perform other CRUD operations.
3.5 Create the Main file
Create a Spring boot application and query custom methods.
@SpringBootApplication public class SpringlikequeryApplication implements CommandLineRunner { // Main method public static void main(String[] args) { SpringApplication.run(SpringlikequeryApplication.class, args); } /* Using JPA repository Output: [Product{id=1, name='Tablet1', category='Electronics'}, Product{id=2, name='Tablet1', category='Electronics'}] [Product{id=4, name='Desk', category='Furniture'}] */ @Autowired ProductRepository productRepository; @Override public void run(String... args) throws Exception { System.out.println(productRepository.findByNameLike("Tablet")); System.out.println(productRepository.findByNameLike("Desk")); } }
The given code defines a spring boot application that implements the CommandLineRunner
runner to execute the specific code once the application is started.
3.6 Run the application
Run your Spring Boot application and the application will be started on a port number specified in the application properties file. As soon as the application is started the command runner interface will trigger the run()
method and the output will be printed on the IDE console.
4. Conclusion
Spring Data JPA offers a powerful and convenient framework for interacting with databases in Spring applications. Its ability to reduce boilerplate code, provide built-in and custom query support, and integrate seamlessly with the broader Spring ecosystem makes it an attractive choice for developers. Additionally, features like pagination, sorting, auditing, and versioning enhance its utility in building robust and maintainable data access layers. However, it is essential to be aware of the potential disadvantages, such as the learning curve, performance overhead, limited control over complex queries, and dependency on the Spring framework. Despite these drawbacks, the benefits of Spring Data JPA often outweigh the challenges, making it a valuable tool for many Java developers working on data-centric applications.
5. Download the source code
In this tutorial, we demonstrated how to use JpaRepository
interface and perform a flexible and powerful way to perform SQL interactions.
You can download the full source code of this example here: Spring Boot JpaRepository Example