Giới thiệu về Spring Boot Starter Data JPA

Trong các ứng dụng Spring Boot làm việc với relational database, một dependency rất phổ biến mà các bạn thường hay dùng đó là Spring Boot Starter Data JPA. Chỉ với dependency này, các bạn đã có thể sử dụng Spring Data JPA, Hibernate và nhiều tính năng liên quan đến Jakarta Persistence mà không cần phải tự cấu hình quá nhiều thành phần. Vậy Spring Boot Starter Data JPA thực sự cung cấp những gì? Spring Boot auto-configure những thành phần nào cho Starter này? Và điều gì xảy ra khi ứng dụng Spring Boot khởi động? Trong bài viết này, chúng ta sẽ tìm hiểu Spring Boot Starter Data JPA từ những khái niệm cơ bản đến cơ chế auto-configuration bên trong Spring Boot, các bạn nhé!

Trước tiên, các bạn cần phân biệt một số khái niệm thường bị nhầm lẫn:

  • Spring Boot Starter
  • Spring Data JPA
  • Jakarta Persistence
  • Hibernate

Các thành phần này có mối quan hệ với nhau nhưng không phải là cùng một thứ.

Các bạn có thể hình dung đơn giản như sau:

Nói về Spring Boot Starter thì trong bài viết trước, mình đã giới thiệu với các bạn mục đích của Spring Boot Starter: một dependency descriptor giúp chúng ta dễ dàng khai báo một nhóm dependency cần thiết cho một chức năng cụ thể. Spring Boot Starter Data JPA là một Spring Boot Starter dành cho việc thao tác với các relational database sử dụng Spring Data JPA đó các bạn.

Các bạn có thể tạo mới một Spring Boot project sử dụng Starter Data JPA cùng với một JDBC Driver ví dụ như PostgreSQL Driver như sau:

Kết quả:

Kiểm tra tập tin pom.xml của project này, các bạn sẽ thấy Spring Boot Starter Data JPA dependency được khai báo như sau:

Maven sẽ tải spring-boot-starter-data-jpa cùng với các dependency mà Starter này yêu cầu, như sau:


Spring Boot Starter Data JPA sẽ quản lý dependency và version tương ứng của các thư viện:

  • Spring Boot JPA
  • Spring Data JPA
  • Spring ORM
  • Jakarta Persistence
  • Hibernate
  • Transaction infrastructure

thông qua dependency management của Spring Boot.

Bây giờ chúng ta sẽ xem vai trò của từng dependency như thế nào, các bạn nhé!

Spring Boot JPA

Spring Boot JPA cung cấp các Jakarta Persistence support classes, cơ chế auto-configuration và integration với Spring Boot. Mình sẽ có một bài viết chi tiết hơn về cơ chế auto-configuration và integration với Spring Boot của Spring Boot Starter Data JPA sau các bạn nhé.

Spring Data JPA

Spring Data JPA cung cấp abstraction giúp chúng ta làm việc với Jakarta Persistence dễ dàng hơn.

Ví dụ đối với interface StudentRepository:

Các banh không cần tự viết implementation cho interface StudentRepository này. Spring Data JPA sẽ tạo repository implementation/proxy phù hợp trong quá trình khởi động ứng dụng, giúp chúng ta có thể dễ dàng thao tác với database mà không cần phải viết nhiều code.

Spring ORM

Spring ORM sẽ chịu trách nhiệm integrate Jakarta Persistence with Spring Framework đó các bạn. Các class LocalContainerEntityManagerFactoryBean và LocalEntityManagerFactoryBean đều nằm trong module này.

Jakarta Persistence

Jakarta Persistence, trước đây được biết đến với tên gọi JPA, định nghĩa API và specification cho persistence trong Java.

Ví dụ các bạn có thể định nghĩa một entity Student như sau:

Các annotation như:

  • @Entity
  • @Id
  • @GeneratedValue
  • @OneToMany
  • @ManyToOne

đến từ Jakarta Persistence API.

Hibernate

Hibernate là một implementation phổ biến của Jakarta Persistence. Các bạn có thể hiểu đơn giản:

    • Jakarta Persistence là API, specification.
    • Hibernate là implementation cho specification này.

Spring Boot Starter Data JPA sử dụng HIbernate làm implementation mặc định của Jakarta Persistence đó các bạn.

Transaction infrastructure

Spring Boot Starter Data JPA cung cấp các module và cấu hình cần thiết để chúng ta có thể hiện thực transaction management trong ứng dụng của mình. Ví dụ như:

  • spring-tx → cung cấp các abstraction cho phần transaction.
  • spring-orm → integrate giữa Jakarta Persistence/ORM với Spring Framework
  • JpaTransactionManager → quản lý Jakarta Persistence transactions sử dụng EntityManager.
  • @Transactional → cấu hình để Spring biết là chúng ta muốn apply transaction hay không cho một phương thức hoặc tất cả các phương thức trong class nào đó.

Để có cái nhìn rõ ràng hơn giữa Spring Boot Starter Data JPA và Spring Data JPA, các bạn có thể tham khảo bảng tóm tắt như sau:

Chức năng Spring Data JPA Spring Boot Starter Data JPA
Repository abstraction Có Sử dụng Spring Data JPA
JpaRepository Có Sử dụng Spring Data JPA
Hibernate dependency Không phải mục đích chính Được cung cấp
Spring Boot auto-configuration Không Có
DataSource auto-configuration Không Có
JPA infrastructure configuration Cần cấu hình trong môi trường Spring thường Được Spring Boot auto-configure
Yêu cầu Spring Boot Không Có

Do đó, các bạn có thể hiểu: Spring Boot Starter Data JPA không phải là một persistence technology mới. Nó là Spring Boot Starter giúp chúng ta sử dụng Spring Data JPA cùng với JPA/Hibernate và các infrastructure cần thiết một cách thuận tiện hơn.

Bây giờ thì chúng ta hãy thử convert project ví dụ mà mình đã làm trong bài viết trước qua sử dụng Spring Boot Starter Data JPA xem như thế nào, các bạn nhé.

Để Jakarta Persistence có thể làm việc với database, ứng dụng của chúng ta sẽ cần thông tin DataSource. Trong Spring Boot thì các bạn có thể cấu hình như sau:

Với khai báo này thì khi chạy ứng dụng Spring Boot, class DataSourceAutoConfiguration của Spring Boot JDBC có thể phát hiện các dependency và configuration cần thiết để tạo DataSource đó các bạn.

Mình sẽ copy entity class Student và class repository cho entity này là StudentRepository qua project ví dụ trong bài viết này.

Spring Boot cần phát hiện entity Student để Hibernate có thể sử dụng nó trong persistence unit.

Thông thường, Spring Boot có thể sử dụng package và subpackage của application class, trong project ví dụ của mình là SpringBootStarterDataJpaExampleApplication, làm cơ sở cho component scanning và các cơ chế scanning liên quan. Với cấu trúc package như trong project ví dụ của mình thì Spring Boot nó có thể tự động scan để include entity Student, đó các bạn.

Trong những trường hợp package structure đặc biệt, các bạn sử dụng annotation là @EntityScan để chỉ định package chứa thông tin entity! Mình sẽ nói chi tiết về cơ chế này trong một bài viết sau.

Về StudentRepository thì Spring Boot sử dụng class DataJpaRepositoriesAutoConfiguration trong module Spring Boot JPA để tự động cấu hình cho Spring Data JPA repository, đó các bạn. Tương tự như đối với entity class, Spring Boot cũng sử dụng package và subpackage của application class để làm cơ sở cho component scanning, tự động phát hiện các class Repository đang được định nghĩa. Nếu các bạn muốn Spring Boot scan các class Repository này ở một package khác thì các bạn cũng có thể sử dụng annotation @EnableJpaRepositories. Mình cũng sẽ đề cập chi tiết về cơ chế này trong một bài viết sau, các bạn nhé!

Một thành phần rất quan trọng của Jakarta Persistence đó là EntityManagerFactory. EntityManagerFactory được sử dụng để tạo EntityManager. Trong ứng dụng Spring Boot, chúng ta thường không cần tự tạo EntityManagerFactory.

Spring Boot sẽ auto-configure Jakarta Persistence infrastructure dựa trên:

  • DataSource
  • JPA dependencies
  • Hibernate
  • application properties
  • entity classes
  • các Spring configuration khác

Các bạn cũng có thể inject để sử dụng EntityManager nếu muốn. Điều này cho phép ứng dụng sử dụng trực tiếp Jakarta Persistence API bên cạnh Spring Data JPA repositories, đó các bạn.

Để chạy ứng dụng ví dụ này, các bạn có thể thêm một bean của class CommandLineRunner như sau:

Kết quả khi chạy ứng dụng:

Như các bạn thấy thì với ứng dụng Spring Boot, chúng ta không cần viết nhiều code như khi sử dụng Spring Data JPA, mà chúng ta cũng đạt được kết quả như chúng ta mong muốn.

Module Spring Data JPA cung cấp nhiều property để cấu hình cho Jakarta Persistence. Ví dụ như:

Với configuration này, khi chạy ứng dụng, các bạn có thể dễ dàng quan sát SQL được Hibernate generate. Ví dụ:

Một property khác thường được sử dụng:

Property này quyết định cách Hibernate xử lý database schema.

Một số giá trị phổ biến:

  • none
  • validate
  • update
  • create
  • create-drop

Tuy nhiên, các bạn cần đặc biệt cẩn thận khi sử dụng property này trên môi trường production, các bạn nhé. Trên môi trường production, việc quản lý database schema thường nên được thực hiện bằng database migration tools như Flyway hoặc Liquibase thay vì phụ thuộc vào Hibernate schema generation.

Tóm lại, Spring Boot Starter Data JPA là một trong những Spring Boot starter được sử dụng phổ biến nhất trong các ứng dụng làm việc với relational database.

Điều quan trọng nhất các bạn cần hiểu là Starter này không phải là một persistence framework độc lập. Thay vào đó, nó giúp kết hợp nhiều thành phần liên quan đến Spring Data JPA, Jakarta Persistence, Hibernate và cơ chế auto-configuration của Spring Boot, giúp chúng ta có thể thao tác với database một cách dễ dàng hơn trong các ứng dụng Spring Boot.

Spring Boot Starter Data JPA giúp đơn giản hóa việc tích hợp Spring Data JPA, Jakarta Persistence và Hibernate vào Spring Boot application thông qua dependency management và auto-configuration.

Tuy nhiên, việc sử dụng Jakarta Persistence hiệu quả vẫn đòi hỏi chúng ta hiểu về entity mapping, transaction, SQL, database design, query performance và Hibernate behavior, các bạn nhé.

4/5 - (1 bình chọn)

Add Comment