Lazy Loading এবং Eager Loading হল দুটি জনপ্রিয় কৌশল যা JPA এবং Hibernate-এ সম্পর্কিত (relationship) ডেটার লোডিং ম্যানেজ করতে ব্যবহৃত হয়। এই দুটি লোডিং পদ্ধতি ডেটাবেসের সাথে কিভাবে ডেটা লোড হবে তা নির্ধারণ করে এবং এটি পারফরম্যান্স এবং অ্যাপ্লিকেশনের কার্যকারিতা প্রভাবিত করতে পারে।
১. Lazy Loading
Lazy Loading হল একটি পদ্ধতি যেখানে সম্পর্কিত ডেটা শুধুমাত্র যখন প্রয়োজন হবে, তখনই ডাটাবেস থেকে লোড করা হয়। এই পদ্ধতিতে প্রথমে মূল অবজেক্ট লোড হয় এবং সম্পর্কিত অবজেক্টগুলি তখন লোড হয় যখন সেগুলির অ্যাক্সেস করা হয়।
বৈশিষ্ট্য:
- Performance: এটি পারফরম্যান্সের জন্য উপকারী, কারণ শুধুমাত্র প্রয়োজনীয় ডেটা লোড করা হয়, অব্যবহৃত ডেটা লোড করা হয় না।
- N+1 Select Problem: যদি Lazy Loading সঠিকভাবে কনফিগার না করা হয়, তবে এটি N+1 Select সমস্যা সৃষ্টি করতে পারে, যেখানে একাধিক সিলেক্ট কুয়েরি রান হয়, একে একে সম্পর্কিত প্রতিটি অবজেক্টের জন্য।
উদাহরণ (Lazy Loading):
ধরা যাক, একটি Department এবং Employee এর মধ্যে One-to-Many সম্পর্ক রয়েছে, যেখানে একটি Department একাধিক Employee ধারণ করে।
@Entity
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "department", fetch = FetchType.LAZY)
private List<Employee> employees;
// Getters এবং Setters
}
এখানে, Department Entity এর সাথে যুক্ত employees ফিল্ডটি Lazy Loading হিসেবে সেট করা হয়েছে। এর মানে হল, employees তালিকা শুধুমাত্র যখন অ্যাক্সেস করা হবে, তখনই ডাটাবেস থেকে লোড হবে।
public class DepartmentService {
@Autowired
private DepartmentRepository departmentRepository;
public void fetchDepartmentDetails(Long id) {
Department department = departmentRepository.findById(id).get();
System.out.println(department.getName());
// employees লোড হবে না যতক্ষণ না তা অ্যাক্সেস করা হয়
}
}
২. Eager Loading
Eager Loading হল একটি পদ্ধতি যেখানে সম্পর্কিত ডেটা প্রথমেই লোড করা হয়, যখন মূল অবজেক্টটি লোড করা হয়। অর্থাৎ, ডেটা লোড করার সময় সম্পর্কিত সব ডেটাও একসাথে লোড হয়।
বৈশিষ্ট্য:
- Performance: এটি প্রাথমিকভাবে পারফরম্যান্সের জন্য উপকারী নয়, কারণ সম্পর্কিত সব ডেটা একসাথে লোড করা হয়, যেটি অপ্রয়োজনীয় ডেটা লোড করতে পারে।
- No N+1 Problem: Eager loading ব্যবহার করলে, N+1 Select সমস্যা সাধারণত দেখা দেয় না, কারণ সম্পর্কিত ডেটা একবারেই লোড হয়ে যায়।
উদাহরণ (Eager Loading):
@Entity
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "department", fetch = FetchType.EAGER)
private List<Employee> employees;
// Getters এবং Setters
}
এখানে, Department Entity এর সাথে যুক্ত employees ফিল্ডটি Eager Loading হিসেবে সেট করা হয়েছে। এর মানে হল, Department অবজেক্ট লোড করার সাথে সাথে সম্পর্কিত employees ডেটাও ডাটাবেস থেকে লোড হয়ে যাবে।
public class DepartmentService {
@Autowired
private DepartmentRepository departmentRepository;
public void fetchDepartmentDetails(Long id) {
Department department = departmentRepository.findById(id).get();
System.out.println(department.getName());
// employees লোড হবে এখানে
}
}
Lazy vs Eager Loading: তুলনা
| বৈশিষ্ট্য | Lazy Loading | Eager Loading |
|---|---|---|
| Loading Timing | ডেটা যখন প্রয়োজন হবে তখনই লোড হবে | সম্পর্কিত সব ডেটা প্রথম থেকেই লোড হয়ে যাবে |
| Performance | পারফরম্যান্সের জন্য ভাল, শুধুমাত্র প্রয়োজনীয় ডেটা লোড হয় | পারফরম্যান্সে প্রভাব ফেলতে পারে, কারণ সব ডেটা একসাথে লোড হয় |
| Memory Usage | কম মেমরি ব্যবহার, কারণ অপ্রয়োজনীয় ডেটা লোড হয় না | বেশি মেমরি ব্যবহার, কারণ সম্পর্কিত সব ডেটা একসাথে লোড হয় |
| Use Case | বড় এবং কমপ্লেক্স ডেটাবেস, যখন সম্পর্কিত ডেটার অ্যাক্সেস প্রয়োজন হয় | ছোট অ্যাপ্লিকেশন বা সহজ সম্পর্ক, যেখানে সব সম্পর্কিত ডেটা একসাথে দরকার |
| N+1 Problem | যদি সঠিকভাবে হ্যান্ডেল না করা হয় তবে N+1 Select সমস্যা হতে পারে | N+1 সমস্যা থাকে না, কারণ একবারে সব ডেটা লোড হয় |
N+1 Select Problem এবং এটি কিভাবে সমাধান করবেন
N+1 Select Problem একটি সাধারণ সমস্যা যা Lazy Loading ব্যবহারের সময় ঘটে, বিশেষত যখন One-to-Many অথবা Many-to-Many সম্পর্ক থাকে। এই সমস্যা তখন ঘটে যখন একটি মূল রেকর্ড লোড করা হয় এবং তার সাথে সম্পর্কিত রেকর্ডগুলো একাধিক কুয়েরি দিয়ে লোড হয়।
সমস্যা:
public class DepartmentService {
@Autowired
private DepartmentRepository departmentRepository;
public void fetchDepartmentDetails(Long id) {
Department department = departmentRepository.findById(id).get();
System.out.println(department.getName());
// Lazy loading: Each employee of department is loaded in separate query
for (Employee employee : department.getEmployees()) {
System.out.println(employee.getName());
}
}
}
এখানে, প্রথমে Department লোড হয় এবং তারপর employees লোড করার জন্য আলাদা কুয়েরি চলে, যার ফলে অনেক কুয়েরি রান হয়।
সমাধান (Fetch Join):
Fetch Join ব্যবহার করে এই সমস্যা এড়ানো যায়। এটা একসাথে সমস্ত সম্পর্কিত ডেটা লোড করে।
@Query("SELECT d FROM Department d JOIN FETCH d.employees WHERE d.id = :id")
Department findByIdWithEmployees(@Param("id") Long id);
এখানে, JOIN FETCH ব্যবহার করা হয়েছে, যাতে Department এবং তার সম্পর্কিত employees একসাথে লোড হয়।
সারাংশ
- Lazy Loading হল এমন একটি পদ্ধতি যেখানে সম্পর্কিত ডেটা শুধুমাত্র যখন প্রয়োজন হবে, তখনই লোড করা হয়। এটি পারফরম্যান্সের জন্য উপকারী হতে পারে, তবে N+1 Select Problem সৃষ্টি করতে পারে যদি সঠিকভাবে ব্যবস্থাপনা না করা হয়।
- Eager Loading হল এমন একটি পদ্ধতি যেখানে সম্পর্কিত ডেটা প্রথমেই লোড হয়ে যায়। এটি সাধারণত ছোট অ্যাপ্লিকেশন এবং সহজ সম্পর্কের জন্য উপযুক্ত, তবে বড় ডেটাসেটে অতিরিক্ত মেমরি ব্যবহার করতে পারে।
প্রত্যেকটি পদ্ধতির নিজস্ব সুবিধা এবং দুর্বলতা রয়েছে, এবং আপনার অ্যাপ্লিকেশনের প্রয়োজন অনুসারে সঠিক পদ্ধতি নির্বাচন করা উচিত।
Read more