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 का मुख्य लाभ
जब हम इसे @ManyToMany एनोटेशन के साथ निर्दिष्ट करते हैं तो हमें LazyCollectionOption.EXTRA का सबसे मजबूत लाभ दिखाई देता है । आइए अपना पुराना मामला लेते हैं जहां हमारे पास एक कर्मचारी है, एक कार्य है, और हम एक उपयोगकर्ता को कई कार्य सौंप सकते हैं।
हमारी जावा कक्षाएं इस तरह दिखती हैं:
कर्मचारी वर्ग :
@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>();
}
और कर्मचारी कार्य वर्ग :
@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 एनोटेशन है, तो कर्मचारियों का संग्रह (टास्क क्लास का) और टास्क कलेक्शन (कर्मचारी वर्ग का) कभी भी डेटाबेस से लोड नहीं किया जाएगा ।
जब यह कोड निष्पादित किया जाता है, तो केवल एक रिकॉर्ड कर्मचारी_कार्य सेवा तालिका में डाला जाएगा, जैसा कि आपको याद है, ऐसा कुछ दिखता है:
कर्मचारी_कार्य तालिका :कर्मचारी आयडी | कार्य_आईडी |
---|---|
1 | 1 |
2 | 2 |
5 | 3 |
5 | 4 |
5 | 5 |
4 | 7 |
6 | 8 |
4 | 101 |
जोड़ी गई पंक्ति को हरे रंग में हाइलाइट किया गया है। इस लाइन को जोड़ने के लिए, आपको डेटाबेस से संग्रह लोड करने की आवश्यकता नहीं है - हाइबरनेट इसके बिना करेगा। यह ठीक ऐसा मामला है जब LazyCollectionOption.EXTRA डेटाबेस के साथ काम को बहुत तेज करता है।
एन+1 समस्या
लेकिन, निश्चित रूप से, इस विधा का एक नकारात्मक पहलू भी है। उदाहरण के लिए, 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 प्रश्न करेगा, हालाँकि यह एक के साथ कर सकता है। यदि आपको पहले से पता होता कि आपको इस वर्ग की सभी वस्तुओं की आवश्यकता होगी।
GO TO FULL VERSION