post-image

Hibernate FetchType là gì? Phân biệt FetchType Lazy với Eager

JDBC & Hibernate

Hibernate FetchType là gì?

Trong Hibernate, FetchType là một thuộc tính trong các annotation @OneToOne, @OneToMany, @ManyToOne, @ManyToMany, được dùng để định nghĩa phương thức lấy các đối tượng liên quan.

Ví dụ mình có quan hệ sau:

Hibernate FetchType là gì? Phân biệt FetchType Lazy với Eager

Quan hệ giữa company và employee là một-nhiều.

Khi mapping sang class với Hibernate sẽ như sau:

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

Annotation @OneToMany định nghĩa quan hệ giữa company và employee là 1-n. Trong đó có thuộc tính fetch:

  • fetch = FetchType.LAZY tức là khi bạn find, select đối tượng Company từ database thì nó sẽ không lấy các đối tượng Employee liên quan
  • fetch = FetchType.EAGER tức là khi bạn find, select đối tượng Company từ database thì tất cả các đối tượng Employee liên quan sẽ được lấy ra và lưu vào listEmployee

* Lưu ý:

  • fetch = FetchType.LAZY tức là mặc định không lấy ra các đối tượng liên quan nhưng bên trong transaction, bạn gọi method company.getListEmployee() thì nó vẫn có dữ liệu nhé, bởi vì khi bạn gọi method nó sẽ query các đối tượng Employee liên quan và lưu vào listEmployee, và khi kết thúc transaction listEmployee sẽ chứa các employee liên quan. Tuy nhiên nếu bạn không gọi method đó thì listEmployee không có dữ liệu và khi kết thúc transaction listEmployee sẽ không có đối tượng employee nào
  • fetch = FetchType.EAGER thì khi lấy đối tượng Company là nó mặc định query luôn các đối tượng Employee liên quan và lưu vào listEmployee, do đó khi kết thúc transaction, listEmployee sẽ có chứa các đối tượng Employee của Company đó.

FetchType mặc định

  • Với annotation @ManyToOne  @OneToOne thì fetchType mặc định là EAGER
  • Với annotation @ManyToMany và @OneToMany thì fetchType mặc định là LAZY

Có sự khác nhau như trên là vì với annotation @ManyToOne, và @OneToOne thì khi select với fetchType = EAGER nó chỉ lấy ra nhiều nhất 1 đối tượng liên quan nên không ảnh hưởng gì tới performance. Còn nếu sử dụng fetchType = EAGER với @ManyToMany, @OneToMany thì có thể nó lấy ra rất nhiều đối tượng liên quan dẫn tới làm giảm hiệu năng, tốn bộ nhớ.

Ưu nhược điểm của mỗi loại FetchType

Với FetchType = LAZY(Lazy Loading):

  • Ưu điểm: tiết kiệm thời gian và bộ nhớ khi select
  • Nhược điểm: gây ra lỗi LazyInitializationException, khi muốn lấy các đối tượng liên quan phải mở transaction 1 lần nữa để query

Với FetchType = EAGER(Eager Loading):

  • Ưu điểm: có thể lấy luôn các đối tượng liên quan, xử lý đơn giản, tiện lợi
  • Nhược điểm: tốn nhiều thời gian và bộ nhớ khi select, dữ liệu lấy ra bị thừa, không cần thiết.

Tham khảo khóa học lập trình web 6 tháng, đảm bảo 100% công việc đầu ra!

Nguồn:

https://stackjava.com/hibernate/hibernate-fetchtype-la-gi-phan-biet-fetchtype-lazy-voi-eager.html

https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/FetchType.html

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *