Chuyển đến nội dung chính

Eager/Lazy Loading In Hibernate


Eager/Lazy Loading In Hibernate


Following technologies being used:

  1. Spring Boot 2
  2. Maven
  3. Eclipse

1. Introduction

Khi làm việc với ORM chắc hẳn các bạn sẽ bắt gặp 2 loại eagerloading lazyloading. Ở bài viết này tôi sẽ trình bày về sự khác biệt giữa hai loại này.

2. Maven Dependencies

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>   
    <version>5.2.2.Final</version>
</dependency>
ở đây chúng ta sử dụng hibernate 5.

3. Eager and Lazy Loading

Eager Loading được thiết kế giúp cho việc khởi tạo đối tượng ngay lập tức.

Lazy Loading được thiết kế giúp cho việc trì hoãn việc khởi tạo đối tưởng miễn là có thể theo dõi ví dụ sau: class UserLazy
@Entity
@Table(name = "USER")
public class UserLazy implements Serializable {
 
    @Id
    @GeneratedValue
    @Column(name = "USER_ID")
    private Long userId;
 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
    private Set<OrderDetail> orderDetail ;
 
    // standard setters and getters
    // also override equals and hashcode
 
}
class OrderDetail

@Entity
@Table (name = "USER_ORDER")
public class OrderDetail implements Serializable {
     
    @Id
    @GeneratedValue
    @Column(name="ORDER_ID")
    private Long orderId;
     
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="USER_ID")
    private UserLazy user;
 
    // standard setters and getters
    // also override equals and hashcode
 
}
OrderDetail Annotation @OneToMany định nghĩa quan hệ giữa UserLazy và OrderDetail là 1-n.
Trong đó có thuộc tính fetch:
fetch = FetchType.LAZY tức là khi bạn find, select đối tượng UserLazy
 

từ database thì nó sẽ không lấy các đối tượng OrderDetail liên quan nếu bạn sử dụng:

fetch = FetchType.EAGER tức là khi bạn find, select đối tượng UserLazy từ database thì tất cả các đối tượng OrderDetail liên quan sẽ được lấy ra và lưu vào set orderDetail

Lưu ý
fetch = FetchType.LAZY tức là mặc định không lấy ra các đối tượng quan hệ dù trong cùng một transaction chỉ khi bạn gọi getOrderDetail() thì lúc này truy vấn lấy dữ liệu danh sách orderDetail sẽ được thực hiện.
 Nếu bạn không gọi getOrderDetail() thì list này sẽ không có dữ liệu và kết thúc transaction sẽ không có danh sách orderDetail nào cả =))
fetch = FetchType.EAGER thì khi lấy đối tượng UserLazy là nó mặc định query luôn các đối tượng OrderDetail liên quan và lưu vào set orderDetail, do đó khi kết thúc transaction, set orderDetail sẽ có chứa các đối tượng UserLazy của OrderDetail đó.

4 FetchType mặc định

Mặc đinh:
annotation @ManyToOne và @OneToOne thì fetchType EAGER là mặc định
annotation @ManyToMany và @OneToMany thì fetchType LAZY là mặc định

5. So sánh

Với FetchType = LAZY(Lazy Loading):
Ưu điểm:
  • Tiết kiệm thời gian
  • Tiết kiệm bộ nhớ 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 hay còn gọi là n+1 query
Với FetchType = EAGER(Eager Loading):
Ưu điểm:
  • Lấy trực tiếp các đối tượng liên quan
  • Xử lý đơn giản Nhược điểm:
  • Tốn nhiều thời gian và bộ nhớ khi truy vấn select
  • Dữ liệu lấy ra bị thừa nếu không dùng tới.

Nhận xét

Bài đăng phổ biến từ blog này

Spring boot Download and upload File ( phần 1 Backend )

Ở bài viết này mình sẽ trình bày mình sẽ tring bày làm thế nào để upload và download file trong một  Restful spring boot web service (  Công nghệ sử dụng: Spring Boot Mysql JPA/Hibernate Content Project:     Cấu Trúc thư mục : JPA and MySQL dependencies   Tôi sẽ lưu trữ file trong mysql database vậy nên cần dependencies về mysql  và jpa. File pom  : < dependencies > < dependency > < groupId > org.springframework.boot </ groupId > < artifactId > spring-boot-starter-web </ artifactId > </ dependency > < dependency > < groupId > org.springframework.boot </ groupId > < artifactId > spring-boot-starter-data-jpa </ artifactId > </ dependency > < dependency > < groupId > mysql </ groupId > < artifactId > mysql-connector-java </ artifactId > < scope > runtime </ scope > </ dependency...

Giới thiệu về Sevices và dependency injection trong Angular 7

Sevice là một danh mục rộng bao gồm bất kỳ value, function, hoặc tính năng mà ứng dụng cần. Một service là một class thông thượng được định nghĩa với mục đích rõ ràng. Angurlar phân biệt các thành phần từ các service để tăng tính modul và khả năng tái sử dụng. Một Component có thể giao một số công việc cho các service  như fetching data từ server, validating user input, hoặc logging trực tiếp... Bằng việc xác định xử lý các tiến trình trong một lớp  injectable service class  Bạn sẽ làm các tác vụ đó trở nên có sẵn tới bất kỳ component. Bạn cũng có thể làm ứng dụng của bạn thích ứng hơn bằng cách tiêm nhiều provider của cùng loại dịch vụ. Service examples Dưới đây là một ví dụ show consolog trên browser  src/app/logger.service.ts (class) export class Logger { log(msg: any) { console.log(msg); } error(msg: any) { console.error(msg); } warn(msg: any) { console.warn(msg); } } Service có thể được phụ thuộc vào các Service khác. Theo ví dụ dưới đây , ...