Người dịch: Nguyễn Văn Vượng, lập trình viên  Spring Boot tại Techmaster từ 7/2020
Nguồn dịch: https://vladmihalcea.com/a-beginners-guide-to-jpa-hibernate-entity-state-transitions/

1. Giới thiệu

Hibernate thay đổi tư duy lập trình viên từ câu lệnh SQL sang chuyển đổi trạng thái entity. Khi entity được quản lý bằng Hibernate thì mọi thay đổi của entity sẽ được tự động truyền vào trong cơ sở dữ liệu (database).

Thao tác với mô hình các entity (cùng với liên kết của chúng) dễ dàng hơn nhiều so với việc viết và bảo trình bằng câu lệnh SQL. Không có thư viện ORM thì mỗi khi thêm một cột mới vào sẽ đòi hỏi sửa đổi tất cả các câu lệnh INSERT/UPDATE liên quan

Tuy nhiên Hibernate cũng không phải là thứ vũ khí thần thánh. Hibernate không giải thoát chúng ta ra khỏi sự lo lắng về việc các câu lệnh SQL được thực thi khi nào và như thế nào. Trên entity để có thể kiểm soát được Hibernate lại không hề đơn giản vì nó đòi hỏi ta phải kiểm soát được toàn bộ các câu lệnh SQL mà Hibernate thực thi thay cho chúng ta. Ý nói khi bạn viết lệnh Java với Hibernate xong, đôi khí bạn vẫn cần phải debug để xem câu lệnh SQL được Hibernate sinh ra có đúng theo ý bạn không.

2. Trạng thái entity

Như đã nói ở trên, Hibernate quản lý các entity được liên kết nhưng để một entity được quản lý thì nó phải ở đúng trạng thái.

Đầu tiên ta cần định nghĩa tất cả các trạng thái của entity:

New (Mới tạo ra, chưa được lưu xuống CSDL):

Một object vừa mới được tạo ra mà chưa được kết nối với Hibernate và cũng chưa được ánh xạ vào bất cứ bảng nào trong database thì sẽ được coi như là ở trạng thái New (Transient)

Để chuyển sang trạng thái Persistent (bền bỉ), chúng ta phải gọi chính xác đến method persist của EntityManager hoặc sử dụng cơ chế bắc cầu.

Persistent (được ghi xuống CSDL và quản lý trong Persistence Context):

Thực thể Persistent đã được ánh xạ vào trong database và được quản bị bởi Persistence Context đang hoạt động. Bất cứ thay đổi nào tác động lên entity sẽ được ghi nhận và  cuồi cùng được ghi ổn định vào trong cơ sở dữ liệu trong lệnh Session flush. Với Hibernate ta không cần tự thực thi những câu lệnh INSERT/UPDATE/ DELETE nữa. Hibernate thực thi theo cách làm việc transactional write-behind và các thay đổi sẽ được đồng bộ hóa tại bước cuối cùng của Session flush

Detached (tạm thời tách ra khỏi Persistence Context)

Một khi Persistence Context đang chạy đã đóng lại, mọi entity được liên kết trước đó sẽ bị tách ra. Các thay đổi tiếp theo sau đó sẽ không còn được theo dõi và động bộ hóa vào trong database nữa. Để liên kết lại các entity bị tách ra này ta có 2 cách:

  • Cách 1: Reattaching: Hibernate (trừ JPA 2.1) hỗ trợ hoạt động liên kết lại thông qua method update của Session. 1 Hibernate session chỉ có thể liên kết 1 đối tượng Entity với hàng database có sẵn. Bởi vì Persistence Context hoạt động như 1 bộ đệm trong bộ nhớ (lvl1) và mỗi một giá trị (entity) sẽ được liên kết với 1 khóa (kiểu entity và dữ liệu xác định). Một entity chỉ có thể liên kết lại được chỉ khi mà không có bất cứ một JVM object nào khác ánh xạ cùng 1 row trong database đã được liên kết với Hibernate session hiện tại.

  • Cách 2: Merging: sao chép trạng thái entity bị tách ra (nguồn) vào 1 entity instance được quản lý (đích). Nếu như entity này không có sự tương ứng với nó trong session hiện tại thì 1 entity sẽ được lấy từ database ra.

Detached object instance vẫn sẽ ở trạng thái detached sau khi quá trình merging kết thúc

Removed:

Mặc dù JPA chỉ cho phép xóa những entity đã được quản lý, Hibernate vẫn có thể xóa được những detached entity (nhưng phải thông qua method delete của session). Entity ở trạng thái removed thực ra chưa hoàn toàn bị xóa cho đến khi Session flush được gọi.

3. Thay đổi trạng thái entity

Để thay đổi trạng thái của JPA entity, chúng ta cần sử dụng các method của EntityManager như hình dưới đây:

Khi Hibernate session interface mở rộng (extends) từ JPA EntityManager, nó cũng cung cấp thêm một số các phương thức đặc biệt mà ta có thể sử dụng để thay đổi trạng thái của entity như hình minh họa dưới đây


 

4. Kết luận:

Những Interface này định nghĩa về hoạt động thay đổi trạng thái của Entity chúng ta phải gọi nó một cách rõ ràng để thông báo cho Hibernate về sự thay đổi trạng thái của entity. Tại quá trình flush, sự thay đổi về trạng thái của entity sẽ được thực thể hóa thành câu lệnh DML (Data Manipulation Language).