LazyCollectionOption.EXTRA জানা
কিন্তু সবচেয়ে আগ্রহের বিষয় হল LazyCollectionOption.EXTRA মান। আপনি যদি এটিকে @LazyCollection টীকাটির মান হিসাবে উল্লেখ করেন , তাহলে হাইবারনেট যতদিন সম্ভব সংগ্রহের উপাদানগুলি লোড করতে বিলম্ব করবে।
আপনি যদি একটি সংগ্রহে উপাদানের সংখ্যা পেতে চেষ্টা করেন:
User user = session.load(User.class, 1);
List<Comment> comments = user.getComments();
int count = commetns.size();
তারপর এই সমস্ত কোডের জন্য, হাইবারনেট শুধুমাত্র একটি প্রশ্ন চালাবে:
SELECT COUNT(id) FROM comment WHERE user_id = 1;
যাইহোক, যদি আপনি সংগ্রহ থেকে একটি মন্তব্য পেতে চান, উদাহরণস্বরূপ নম্বর 3:
User user = session.load(User.class, 1);
List<Comment> comments = user.getComments();
Comment comment = commetns.get(3);
তারপর প্রশ্ন ওঠে: হাইবারনেট কিভাবে জানবে যে উপাদানটি মেমরিতে সমস্ত উপাদান লোড না করেই তৃতীয়?
এই সমস্যাটি সমাধানের জন্য, মন্তব্য টেবিলে একটি অতিরিক্ত কলাম তৈরি করার প্রস্তাব করা হয়েছে, যা মন্তব্য সংগ্রহে মন্তব্যের ক্রমিক সংখ্যা সংরক্ষণ করবে। এবং এর জন্য আপনার একটি বিশেষ টীকা দরকার - @OrderColumn ।
এই সমাধানটি দেখতে কেমন হবে তা এখানে:
@Entity
@Table(name=”user”)
class User {
@Column(name=”id”)
public Integer id;
@OneToMany(cascade = CascadeType.ALL)
@LazyCollection(LazyCollectionOption.EXTRA)
@OrderColumn(name = "order_id")
public List<Comment> comments;
}
LazyCollectionOption.EXTRA এর প্রধান সুবিধা
আমরা LazyCollectionOption.EXTRA এর সবচেয়ে শক্তিশালী সুবিধা দেখতে পাই যখন আমরা এটিকে @ManyToMany টীকা দিয়ে নির্দিষ্ট করি । আমাদের পুরানো কেস ধরা যাক যেখানে আমাদের একজন কর্মচারী আছে, একটি টাস্ক আছে এবং আমরা একজন ব্যবহারকারীকে অনেকগুলি কাজ বরাদ্দ করতে পারি।
আমাদের জাভা ক্লাস দেখতে এইরকম:
কর্মচারী শ্রেণী :
@Entity
@Table(name=”employee”)
class Employee {
@Column(name=”id”)
public Integer id;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name="employee_task",
joinColumns= @JoinColumn(name="employee_id", referencedColumnName="id"),
inverseJoinColumns= @JoinColumn(name="task_id", referencedColumnName="id") )
@LazyCollection(LazyCollectionOption.EXTRA)
private Set<EmployeeTask> tasks = new HashSet<EmployeeTask>();
}
এবং EmployeeTask ক্লাস :
@Entity
@Table(name=”task”)
class EmployeeTask {
@Column(name=”id”)
public Integer id;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name="employee_task",
joinColumns= @JoinColumn(name="task_id", referencedColumnName="id"),
inverseJoinColumns= @JoinColumn(name=" employee_id", referencedColumnName="id") )
@LazyCollection(LazyCollectionOption.EXTRA)
private Set<Employee> employees = new HashSet<Employee>();
}
এবং পরিচালকের কাছে একটি কাজ যোগ করতে, আপনাকে এই কোডের মতো কিছু লিখতে হবে:
Employee director = session.find(Employee.class, 4);
EmployeeTask task = session.find(EmployeeTask.class, 101);
task.employees.add(director);
session.update(task);
session.flush();
সুতরাং, টাস্ক ক্লাসের কর্মচারীদের ক্ষেত্রে যদি LazyCollectionOption.EXTRA টীকা থাকে, তাহলে কর্মচারী সংগ্রহ (টাস্ক ক্লাসের) এবং টাস্ক সংগ্রহ (কর্মচারী শ্রেণীর) ডাটাবেস থেকে কখনই লোড হবে না ।
যখন এই কোডটি কার্যকর করা হয়, শুধুমাত্র একটি রেকর্ড কর্মচারী_টাস্ক পরিষেবা টেবিলে ঢোকানো হবে, যা আপনার মনে আছে, এইরকম কিছু দেখায়:
কর্মচারী_টাস্ক টেবিল :কর্মচারী আইডি | task_id |
---|---|
1 | 1 |
2 | 2 |
5 | 3 |
5 | 4 |
5 | 5 |
4 | 7 |
6 | 8 |
4 | 101 |
যোগ করা লাইনটি সবুজ রঙে হাইলাইট করা হয়েছে। এই লাইনটি যোগ করতে, আপনাকে ডাটাবেস থেকে সংগ্রহগুলি লোড করতে হবে না - হাইবারনেট এটি ছাড়াই করবে। LazyCollectionOption.EXTRA ডাটাবেসের সাথে কাজকে ব্যাপকভাবে গতি বাড়ায় তখন এটি ঠিক হয়।
N+1 সমস্যা
কিন্তু, অবশ্যই, এই মোড একটি downside আছে. উদাহরণস্বরূপ, LazyCollectionOption.EXTRA টীকা একটি N+1 সমস্যা তৈরি করে ।
আপনি যদি আপনার ব্যবহারকারীর সমস্ত মন্তব্যের মধ্য দিয়ে যাওয়ার সিদ্ধান্ত নেন:
User user = session.load(User.class, 1);
List<Comment> comments = user.getComments();
for (Comment comment : comments) {
System.out.println(comment);
}
তারপর হাইবারনেট প্রতিটি মন্তব্য অবজেক্টের জন্য একটি পৃথক অনুরোধে কার্যকর করবে। এবং সমস্ত মন্তব্যের গণনা পেতে আরও একটি অতিরিক্ত প্রশ্ন। এটি উল্লেখযোগ্যভাবে কোডটি ধীর করতে পারে।
যদি আপনার ব্যবহারকারীর 1000টি মন্তব্য থাকে, তাহলে হাইবারনেট এই কোডটি কার্যকর করার জন্য ডাটাবেসে 1001টি প্রশ্ন করবে, যদিও এটি একটির সাথে করতে পারে। আপনি যদি আগে থেকে জানতেন যে আপনার এই শ্রেণীর সমস্ত বস্তুর প্রয়োজন হবে।