KIẾN THỨC  


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


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.

Trước tiên, hãy nói về khái niệm.
FetchType.EAGER và FetchType.LAZY là 2 kiểu fetch strategy khác nhau trong Hibernate, cho phép quản lý việc load các đối tượng trong các mối quan hệ giữa các đối tượng.

FetchType.EAGER:
- Khi sử dụng FetchType.EAGER, Hibernate sẽ tự động tải tất cả các đối tượng liên quan trong quá trình lấy đối tượng gốc từ database. Nó có nghĩa là các liên kết của đối tượng sẽ được lấy ra và tải vào bộ nhớ cùng với đối tượng gốc. Vì vậy, sử dụng FetchType.EAGER có thể gây tốn nhiều tài nguyên bộ nhwos và làm chậm tốc độ thực thi của chương trình,

FetchType.LAZY:
- Khi sử dụng FetchType.LAZY, Hibernate sẽ chỉ tải các đối tượng liên quan khi cần thiết. Các đối tượng liên quan sẽ không được tải vào bộ nhớ cùng với đối tượng gốc, mà sẽ được tải vào bộ nhớ khi ta yêu cầu truy cập đến các liên kết này. Sử dụng FetchType.LAZY giúp tiết kiệm tài nguyên bộ nhớ và cải thiện hiệu suất của chương trình.

Hãy thử ví dụ, giả sử chúng ta có 2 đối tượng, một là đối tượng cha "Parent" và một là đối tượng con "Child". Đối tượng cha "Parent" có mối quan hệ One-to-Many với đối tượng con "Child".


@Entity
@Table(name = "parent_table")
public class Parent {
    //...
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "parent")
    private List < Child> listChild = new ArrayList < > ();
}


 - Nếu chúng ta sử dụng FetchType.EAGER: Khi lấy đối tượng cha "Parent" từ database (tức là find hay select), tất cả đối tượng con "Child" liên quan sẽ được tải vào bộ nhớ cùng với đối tượng cha "Parent", như trong đoạn code ví dụ thì sẽ được lưu vào listChild.
- Nếu chúng ta sử dụng FetchType.LAZY: Khi lấy đối tượng cha "Parent" từ database (tức là find hay select), các đối tượng con "Child" sẽ không được tải vào bộ nhớ cùng với đối tượng cha "Parent".

FetchType mặc định

- Với annotation @ManyToOne và @OneToOne thì fetch type mặc định là EAGER: anh em có thể dễ dàng đoán được rằng 2 annotation này đều là "..toOne", nghĩa là khi select/find với fetch type là EAGER nó chỉ lấy tối đa 1 đối tượng liên quan nên không ảnh hưởng gì đến performance.
- Với annotation @ManyToMany và @OneToMany thì fetch type mặc định là LAZY: vì đều là "..toMany" nên việc fetch bằng LAZY sẽ không ảnh hưởng đến hiệu năng và bộ nhớ.

Nguồn:

Post a Comment