సమస్య యొక్క వివరణ

మేము పైన చెప్పినట్లుగా, LazyCollectionOption.EXTRA ఉల్లేఖనానికి సమస్య ఉంది - ఇది ప్రతి వస్తువు కోసం డేటాబేస్కు ప్రత్యేక అభ్యర్థనను నిర్వహిస్తుంది. మా పేరెంట్ ఆబ్జెక్ట్‌ల కోసం అన్ని చైల్డ్ ఆబ్జెక్ట్‌లను వెంటనే లోడ్ చేయాలనుకుంటున్నామని హైబర్నేట్‌కి మనం ఏదో ఒకవిధంగా వివరించాలి.

హైబర్నేట్ డెవలపర్‌లు ఈ సమస్యకు పరిష్కారాన్ని కనుగొన్నారు, HQLలో జాయిన్ ఫెచ్ ఆపరేటర్ .

HQL ప్రశ్న ఉదాహరణ:

select distinct task from Task t left join fetch t.employee order by t.deadline

ఈ ప్రశ్నలో, ప్రతిదీ ఒకే సమయంలో సరళంగా మరియు సంక్లిష్టంగా ఉంటుంది. దానిని ఒక్కొక్కటిగా నిర్మించడానికి ప్రయత్నిద్దాం.

ఎంపిక 1

మేము అన్ని వస్తువులను డౌన్‌లోడ్ చేయాలనుకుంటున్నాముపని, గడువు ప్రకారం క్రమబద్ధీకరించబడింది. ఆ అభ్యర్థన ఎలా ఉంటుందో ఇక్కడ ఉంది:

select task from Task t order by t.deadline

ప్రతిదీ స్పష్టంగా ఉండగా. కానీ ఫీల్డ్ఉద్యోగిటాస్క్ క్లాస్‌లో ఎక్స్‌ట్రా ఉల్లేఖనతో ఉల్లేఖించబడిన ఉద్యోగుల సేకరణ ఉంటుంది . మరియు ఈ సేకరణ యొక్క వస్తువులు లోడ్ చేయబడవు.

ఎంపిక 2

ఒక వస్తువు కోసం పిల్లల వస్తువులను లోడ్ చేయడానికి హైబర్నేట్‌ని బలవంతం చేయండిపని.

select task from Task t join fetch t.employee order by t.deadline

సహాయంతో, మేము మా ప్రశ్నలో టాస్క్ మరియు ఎంప్లాయీ ఎంటిటీలను స్పష్టంగా బంధిస్తాము. మేము ఈ ఫీల్డ్‌లలో @ManyToMany ఉల్లేఖనాలను ఉపయోగిస్తున్నందున హైబర్నేట్‌కి ఇది ఇప్పటికే తెలుసు .

కానీ జాయిన్ ఫెచ్‌ని పొందడానికి ఫెచ్ స్టేట్‌మెంట్‌తో దాన్ని పూర్తి చేయడానికి మాకు జాయిన్ స్టేట్‌మెంట్ అవసరం . మా అభ్యర్థనను అమలు చేసినప్పుడు Task.Employee సేకరణలలోని వస్తువులు డేటాబేస్ నుండి లోడ్ చేయబడాలని మేము హైబర్నేట్‌కి ఈ విధంగా చెబుతాము.

ఎంపిక 3

మునుపటి పరిష్కారం కొన్ని దోషాలను కలిగి ఉంది. మొదట, జాయిన్‌ని ఉపయోగించిన తర్వాత, SQL మాకు వస్తువులను తిరిగి ఇవ్వదుపని, ఉద్యోగుల పట్టికలో వాటితో అనుబంధించబడిన వస్తువులు లేవు. ఇన్నర్ జాయిన్ సరిగ్గా ఇలాగే పని చేస్తుంది .

కాబట్టి మనం ఎడమ ఆపరేటర్‌తో మన జాయిన్‌ను పెంచుకోవాలి మరియు దానిని లెఫ్ట్ జాయిన్‌గా మార్చాలి . ఉదాహరణ:

select task from Task t left join fetch t.employee order by t.deadline

ఎంపిక 4

అయితే అంతే కాదు. మీ కోడ్‌లో ఎంటిటీల మధ్య సంబంధం చాలా నుండి మే వరకు ఉంటే, అప్పుడు ప్రశ్న ఫలితాలలో నకిలీలు ఉంటాయి. అదే వస్తువుపనివేర్వేరు ఉద్యోగులపై (ఉద్యోగి వస్తువులు) కనుగొనవచ్చు.

కాబట్టి మీరు డూప్లికేట్ టాస్క్ ఆబ్జెక్ట్‌ను వదిలించుకోవడానికి ఎంచుకున్న పదం తర్వాత ప్రత్యేకమైన కీవర్డ్‌ని జోడించాలి.

select distinct task from Task t left join fetch t.employee order by t.deadline

ఈ విధంగా 4 దశల్లో మేము ప్రారంభించిన అభ్యర్థనకు వచ్చాము. బాగా, జావా కోడ్ చాలా ఊహించిన విధంగా కనిపిస్తుంది:

String hql = " select distinct task from Task t left join fetch t.employee order by t.deadline";
Query<Task> query = session.createQuery( hql, Task.class);
return query.list();

FETCH పరిమితులలో చేరండి

ఎవ్వరూ పరిపూర్నంగా లేరు. పొందండి ప్రకటనలో కూడా చేరండి. దీనికి చాలా తక్కువ పరిమితులు ఉన్నాయి. మరియు మొదటిది setMaxResults() మరియు setFirstResult() పద్ధతులను ఉపయోగిస్తోంది .

JOIN FETCH స్టేట్‌మెంట్ కోసం, మా హైబర్‌నేట్ చాలా క్లిష్టమైన ప్రశ్నను రూపొందిస్తుంది, దీనిలో మేము మూడు పట్టికలను ఒకటిగా మిళితం చేస్తాము: ఉద్యోగి, పని మరియు ఉద్యోగి_టాస్క్. వాస్తవానికి, ఇది ఉద్యోగులు లేదా టాస్క్‌ల కోసం చేసిన అభ్యర్థన కాదు, కానీ అన్ని తెలిసిన ఉద్యోగి-టాస్క్ జతల కోసం.

మరియు SQL దాని పరిమితి మరియు OFFSET స్టేట్‌మెంట్‌లను ఉద్యోగి-పని జంటల ప్రశ్నకు ఖచ్చితంగా వర్తింపజేయవచ్చు. అదే సమయంలో, మేము ఖచ్చితంగా టాస్క్‌లను (టాస్క్) పొందాలనుకుంటున్నామని HQL ప్రశ్న నుండి స్పష్టంగా అనుసరిస్తుంది మరియు మేము మా FirstResult మరియు MaxResult పారామితులను పునఃపంపిణీ చేస్తే, అవి ప్రత్యేకంగా టాస్క్ ఆబ్జెక్ట్‌లను సూచించాలి.

మీరు ఇలా కోడ్ వ్రాస్తే:

String hql = " select distinct task from Task t left join fetch t.employee order by t.deadline";
Query<Task> query = session.createQuery( hql, Task.class);
       	    query.setFirstResult(0);
        	   query.setMaxResults(1);
return query.list();

అప్పుడు హైబర్నేట్ ఫస్ట్ రిజల్ట్ మరియు మాక్స్ రిజల్ట్‌లను SQL ప్రశ్న యొక్క OFFSET మరియు LIMIT పారామితులకు సరిగ్గా మార్చదు.

బదులుగా, ఇది మూడు పనులను చేస్తుంది:

  • SQL ప్రశ్న సాధారణంగా పట్టిక నుండి మొత్తం డేటాను ఎంచుకుంటుంది మరియు దానిని హైబర్నేట్‌కి తిరిగి ఇస్తుంది
  • హైబర్నేట్ దాని మెమరీలో అవసరమైన రికార్డ్‌లను ఎంచుకుంటుంది మరియు వాటిని మీకు తిరిగి ఇస్తుంది
  • హైబర్నేట్ హెచ్చరిక జారీ చేస్తుంది

హెచ్చరిక ఇలా ఉంటుంది:

WARN [org.hibernate.hql.internal.ast.QueryTranslatorImpl] HHH000104: 
firstResult/maxResults specified with collection fetch; applying in memory!