Katrangan saka masalah

Kaya sing kasebut ing ndhuwur, anotasi LazyCollectionOption.EXTRA duwe masalah - nindakake panjaluk sing kapisah menyang database kanggo saben obyek. Kita kudu nerangake carane Hibernate yen kita pengin langsung mbukak kabeh obyek anak kanggo obyek induk kita.

Pangembang Hibernate wis nemokake solusi kanggo masalah iki, operator njupuk gabungan ing HQL.

Tuladha pitakon HQL:

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

Ing pitakonan iki, kabeh prasaja lan rumit ing wektu sing padha. Ayo dadi nyoba kanggo mbangun Piece dening Piece.

Pilihan 1

Kita pengin ndownload kabeh obyektugas, diurutake miturut deadline. Mangkene panjaluk kasebut:

select task from Task t order by t.deadline

Nalika kabeh wis cetha. Nanging lapanganpegawesaka kelas Tugas bakal ngemot koleksi Karyawan sing dianotasi karo anotasi EXTRA . Lan obyek koleksi iki ora bakal dimuat.

Pilihan 2

Meksa Hibernate kanggo mbukak obyek anak kanggo obyektugas.

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

Kanthi bantuan, kita kanthi tegas ngiket entitas Tugas lan Karyawan ing pitakon kita. Hibernate wis ngerti iki amarga kita nggunakake anotasi @ManyToMany ing kolom kasebut.

Nanging kita butuh statement gabung kanggo ngrampungake karo statement fetch kanggo entuk join fetch . Iki carane kita ngandhani Hibernate yen obyek ing kumpulan Task.employee kudu dimuat saka database nalika panjalukan kita kaleksanan.

Pilihan 3

Solusi sadurunge duwe sawetara kewan omo. Kaping pisanan, sawise nggunakake gabung, SQL ora bakal ngasilake obyek menyang kitatugas, sing ora ana obyek sing ana gandhengane ing tabel Karyawan. Iki pancen cara kerjane gabungan batin .

Dadi, kita kudu nambah gabung karo operator kiwa lan ngowahi dadi gabung kiwa . Tuladha:

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

Pilihan 4

Nanging ora mung kuwi. Yen ing kode sampeyan hubungane antarane entitas akeh-kanggo-mungkin, banjur bakal ana duplikat ing asil pitakon. Objek sing padhatugasbisa ditemokaké ing karyawan beda (Obyek karyawan).

Dadi, sampeyan kudu nambah tembung kunci sing béda sawise tembung pilih kanggo nyingkirake obyek Tugas duplikat.

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

Iki carane ing 4 langkah kita teka menyang request karo kang kita miwiti. Inggih, kode Jawa bakal katon cukup samesthine:

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

GABUNG FETCH Watesan

Ora ana wong sing sampurna. GABUNG FETCH statement uga. Wis cukup sawetara watesan. Lan sing pisanan nggunakake metode setMaxResults () lan setFirstResult () .

Kanggo statement JOIN FETCH, Hibernate kita bakal ngasilake pitakon sing rumit banget sing nggabungake telung tabel dadi siji: karyawan, tugas lan employee_task. Nyatane, iki dudu panjaluk karyawan utawa tugas, nanging kanggo kabeh pasangan tugas karyawan sing dikenal.

Lan SQL bisa ngetrapake pratelan LIMIT lan OFFSET kanthi persis pitakon pasangan tugas karyawan. Ing wektu sing padha, kanthi jelas nderek saka query HQL yen kita pengin entuk tugas sing persis (Tugas), lan yen kita nyebarake maneh paramèter FirstResult lan MaxResult, mula kudu dirujuk khusus menyang obyek Tugas.

Yen sampeyan nulis kode kaya iki:

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

Banjur Hibernate ora bakal bisa ngowahi FirstResult lan MaxResult kanthi bener menyang parameter OFFSET lan LIMIT saka query SQL.

Nanging, bakal nindakake telung perkara:

  • Query SQL bakal milih umume kabeh data saka tabel lan bali menyang Hibernate
  • Hibernate bakal milih cathetan sing dibutuhake ing memori lan bali menyang sampeyan
  • Hibernate bakal ngetokake bebaya

Bebaya bakal kaya mangkene:

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