N +1 Trong ORM(Object Relational Mapping)

N + 1 là gì?

Chúng ta có một bảng PurchaseOrder và bảng PurchaseOrderItem như hình bên dưới.


@Entity
public class PurchaseOrder {
    @Id
    private String id;
    private String customerId;

    @OneToMany(casecade = ALL)
    @JoinColumn(name = purchase_order_id)
    private List<PurchaseOrderItem> purchaseOrderItems = new ArrayList<>();
}
@Entity
public class PurchaseOrderItem {
    @Id
    private String id;
    private String bookId;
}

Chúng ta có thể thấy PurchaseOrder với  PurchaseOrderItem quan hệ 1 – N. Bây giờ chúng ta thử xem một ví dụ, ta sẽ lấy tất cả các PurchaseOrder lên, vậy ta sẽ làm như sau:

SELECT P
FROM PurchaseOrder P
WHERE P.customerId = : customerId

Ok, tới đây mọi chuyện vẫn OK.  Chúng ta có PurchaseOrder và chúng ta thoải moái sử dụng.

Bây giờ mình muốn xuất ra những PurchaseOrderItem của từng PurchaseOrder tương ứng mình sẽ loop qua từng PurchaseOrder và lấy danh sách PurchaseOrderItem.

Tuy nhiên bên dưới Hibernate thực tế nó với mỗi lần duyệt qua một item PurchaseOrder nó sẽ bắn một câu query xuống database để lấy dự liệu lên cho bạn.

Như vậy ta có “1” là câu truy vấn lấy tất cả PurchaseOrder. “N” (số phần tử PurcharseOrder, cũng là số câu truy vấn nó bắn xuống để lấy PurchaseOrderItemtương ứng.  Nó gọi là N + 1 problem trong Hibernate.

Giải quyết

Hibernate cung cấp cho ta 2 cách để giải quyết vấn đề này.

Config fetch = EAGER

@Entity
public class PurchaseOrder {
    @Id
    private String id;
    private String customerId;

    @OneToMany(casecade = ALL, fetch = EAGER)
    @JoinColumn(name = purchase_order_id)
    private List<PurchaseOrderItem> purchaseOrderItems = new ArrayList<>();
}

Cách này thường không được khuyến khích sử dụng vì tính thụ động của nó. Trong trường hợp như trên mình chỉ cần lấy những PurchaseOrder nhưng vì cấu hình như vậy thì nó sẽ load luôn cả PurchaseOrderItem làm tài nguyên.

Sử dụng fetch join

Select * From PurchaseOrder Join fetch PurchaseOrderItem

Bằng cách này chúng ta có thể chủ động lấy data theo ý của mình và làm tăng performane cho ứng dụng.

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x