Ngerteni LazyCollectionOption.EXTRA

Nanging sing paling menarik yaiku nilai LazyCollectionOption.EXTRA. Yen sampeyan nemtokake iku minangka nilai @LazyCollection anotasi , banjur Hibernate bakal tundha loading unsur koleksi kanggo anggere bisa.

Yen sampeyan nyoba entuk jumlah unsur ing koleksi:

User user = session.load(User.class, 1);
List<Comment> comments = user.getComments();
int count = commetns.size();

Banjur kanggo kabeh kode iki, Hibernate mung bakal nglakokake siji pitakon:

SELECT COUNT(id) FROM comment WHERE user_id = 1;

Nanging, yen sampeyan pengin njaluk komentar saka koleksi, contone nomer 3:

User user = session.load(User.class, 1);
List<Comment> comments = user.getComments();
Comment comment = commetns.get(3);

Banjur ana pitakonan: kepiye carane Hibernate ngerti manawa unsur kasebut minangka nomer telu tanpa ngemot kabeh unsur menyang memori?

Kanggo ngatasi masalah iki, disaranake nggawe kolom tambahan ing tabel komentar, sing bakal nyimpen nomer ordinal komentar ing koleksi komentar. Lan uga kanggo iki sampeyan butuh anotasi khusus - @OrderColumn .

Mangkene solusi kasebut bakal katon kaya:

@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;
}

Kauntungan utama LazyCollectionOption.EXTRA

Kita ndeleng kauntungan paling kuat saka LazyCollectionOption.EXTRA nalika kita nemtokake kanthi anotasi @ManyToMany . Ayo dadi njupuk kasus lawas ing ngendi kita duwe Karyawan, Tugas, lan kita bisa nemtokake akeh tugas kanggo siji pangguna.

Kelas Jawa kita katon kaya iki:

Kelas karyawan :

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

}

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

}

Lan kanggo nambah tugas menyang direktur, sampeyan kudu nulis kaya kode iki:

Employee director = session.find(Employee.class, 4);
EmployeeTask task = session.find(EmployeeTask.class, 101);
task.employees.add(director);

session.update(task);
session.flush();

Dadi, yen lapangan karyawan ing kelas Tugas duwe anotasi LazyCollectionOption.EXTRA, mula koleksi karyawan (kelas Tugas) lan koleksi tugas (kelas Karyawan) ora bakal dimuat saka database .

Nalika kode iki dieksekusi, mung siji rekaman sing bakal dilebokake ing tabel layanan employee_task, sing katon kaya mangkene:

tabel tugas_pegawe :
id_pegawe tugas_id
1 1
2 2
5 3
5 4
5 5
4 7
6 8
4 101

Garis sing ditambahake disorot nganggo warna ijo. Kanggo nambah baris iki, sampeyan ora perlu mbukak koleksi saka database - Hibernate bakal nindakake tanpa iku. Iki persis nalika LazyCollectionOption.EXTRA banget nyepetake karya karo database.

Masalah N+1

Nanging, mesthine, mode iki uga duwe kekurangan. Contone, anotasi LazyCollectionOption.EXTRA ngasilake Masalah N+1 .

Yen sampeyan mutusake kanggo mbukak kabeh komentar pangguna:

User user = session.load(User.class, 1);
List<Comment> comments = user.getComments();
for (Comment comment : comments) {
    System.out.println(comment);
}

Banjur Hibernate bakal nglakokake panjaluk sing kapisah kanggo saben obyek Komentar. Lan uga siji pitakon tambahan kanggo ngetung kabeh komentar. Iki bisa Ngartekno alon mudhun kode.

Yen pangguna sampeyan duwe 1000 komentar, banjur Hibernate bakal nggawe 1001 pitakon menyang database kanggo nglakokake kode iki, sanajan bisa ditindakake kanthi siji. Yen sampeyan ngerti luwih dhisik yen sampeyan butuh kabeh obyek ing kelas iki.