post-image

Cascade trong JPA, các loại CascadeType

Tổng quan

Cascade trong JPA, Hibernate là gì? Các loại CascadeType

Cascade là gì?

Cascade là một tính năng giúp quản lý trạng thái của các đối tượng trong một mối quan hệ một cách tự động.

Ví dụ ta có mối quan hệ giữa bảng company và bảng employee như sau:

Cascade trong JPA, Hibernate là gì? Các loại CascadeType

Mối quan hệ giữa company và employee là 1-n (một company chứa nhiều employee).

Khi xóa hoặc update id của một row trong table company sẽ có các trường hợp sau:

  • Trường hợp 1: chưa có employee nào tham chiếu tới company đó (company đó chưa có employee nào) -> xóa / update bình thường.
  • Trường hợp 2: đã có employee tham chiếu tới company đó (company đó đã có employee):
    • 2.1: Mặc định sẽ không có sửa, update vì nó sẽ ảnh hưởng tới các employee đang tham chiếu tới. (ON UPDATE/DELETE = NO ACTION, RESTRICT)
    • 2.2: set company_id của các employee đang tham chiếu tới bằng null (ON UPDATE/ON DELETE = SET NULL) (Tạm hiểu là công ty bị xóa, thay đổi thì các nhân viên sẽ không thuộc công ty nào cả)
    • 2.3: set company_id của các employee bằng id của company sau khi update (cho trường hợp update) . Và xóa tất cả các employee có company_id tham chiếu tới company bị xóa (ON UPDATE/ON DELETE = CASCADE)

Cascade chính là tính năng trong trường hợp 2.3. Khi một bản ghi thay đổi thì nó sẽ tự động update các bản ghi đang tham chiếu tới nó.

Khi nào nên sử dụng Cascade

Lưu ý rằng chính việc tự động update các bản ghi đang tham chiếu tới khiến cho hiệu năng bị giảm xuống cho nên tùy trường hợp mà ta áp dụng nó.

Ví dụ theo logic thông thường, khi xóa 1 company thì ta sẽ xóa tất cả các employee đang tham chiếu tới nó trước rồi sau đấy mới xóa company đó chứ không thực hiện xóa company trước rồi sử dụng cascade để xóa các employee đang tham chiếu tới.

Ta sẽ sử dụng cascade trong các trường hợp dữ liệu tham chiếu ít, các dữ liệu tham chiếu chỉ có ý nghĩa khi gắn liền với đối tượng tham chiếu.

Ví dụ một người có nhiều tên (các tên đó chỉ gắn với người đó), thì khi xóa người đó đi thì ta sẽ xóa luôn các tên đó (vì nếu giữ lại nó sẽ không có tác dụng gì cả) -> trường hợp này dùng cascade.

Sử dụng cascade trong Hibernate, JPA

Trong JPA: ta sẽ thực hiện cấu hình cascade trong annotation @OneToMany (khi truy vấn bằng entityManager)

@Entity
@Table(name = "company")
public class Company {
  //...
  
  @OneToMany(fetch = FetchType.LAZY, mappedBy = "company", cascade = {CascadeType.PERSIST,CascadeType.REMOVE})
  private Set<Employee> listEmployee = new HashSet<>();
  //...
 
}Code language: PHP (php)

Trong Hibernate: ta sẽ cấu hình bằng annotation @Cascade (khi truy vấn bằng session)

@Entity
@Table(name = "company")
public class Company {
  //...
  
  @OneToMany(fetch = FetchType.LAZY, mappedBy = "company")
  @Cascade(value= {org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE})
  private Set<Employee> listEmployee = new HashSet<>();
  //...
  
}Code language: PHP (php)

Nếu muốn dùng cascade trong tất cả các trường hợp, update, delete… ta có thể dùng CascadeType.ALL

Các loại cascade

Các loại cascade trong JPA (khi sử dụng với EntityManagerFactory/EntityManager)

CASCADE MÔT TẢ
ALL Tương ứng với tất cả các loại cascade. cascade={DETACH, MERGE, PERSIST, REFRESH, REMOVE}
DETACH Nếu đối tượng cha bị detached khỏi persistence context thì các đối tượng tham chiếu tới nó cũng bị detached.
MERGE Nếu đối tượng cha được merged vào persistence context, thì các đối tượng tham chiếu tới nó cũng được merged.
PERSIST Nếu đối tượng cha được persisted vào persistence context, thì các đối tượng tham chiếu tới nó cũng được persisted.
REFRESH Nếu đối tượng cha được refreshed ở persistence context hiện tại, thì các đối tượng tham chiếu tới nó cũng được refreshed.
REMOVE Nếu đối tượng cha bị removed khỏi persistence context, thì các đối tượng tham chiếu tới nó cũng được removed.

Các loại cascade trong Hibernate (khi sử dụng với SessionFactory/Session)

Cascade Mô tả
ALL Tương ứng với save, delete, update, evict, lock, replicate, merge, persist
DELETE  
DELETE_ORPHAN Tương ứng với delete + delete orphans
EVICT  
LOCK  
MERGE  
NONE  
PERSIST  
REFRESH  
REPLICATE  
UPDATE  

Trong đó 2 loại cascadeType là DELETE_ORPHANCE và EVICT đã không còn được sử dụng.

Leave a Reply

Your email address will not be published. Required fields are marked *