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>();

}

మరియు ఎంప్లాయీ టాస్క్ క్లాస్ :

@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 డేటాబేస్తో పనిని బాగా వేగవంతం చేసినప్పుడు ఇది సరిగ్గా జరుగుతుంది.

N+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 ప్రశ్నలను చేస్తుంది, అయినప్పటికీ అది ఒకదానితో చేయగలదు. మీకు ఈ తరగతిలోని అన్ని వస్తువులు అవసరమని మీకు ముందే తెలిస్తే.