Differenza tra get() e load() della sessione di Hibernate con esempi

Seduta di Hibernate fornisce diversi metodi per recuperare dati dal database. Due di essi sono – get() e load(). Ci sono anche molti metodi sovraccaricati per questi, che possiamo utilizzare in diverse circostanze. A prima vista, sia get() che load() sembrano simili perché entrambi recuperano i dati dal database, tuttavia ci sono alcune differenze tra di loro, vediamole con un esempio semplice.

package com.journaldev.hibernate.main;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import com.journaldev.hibernate.model.Employee;
import com.journaldev.hibernate.util.HibernateUtil;

public class HibernateGetVsLoad {

	public static void main(String[] args) {
		
		//Lavoro preliminare
		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		Session session = sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		
		//Esempio di get
		Employee emp = (Employee) session.get(Employee.class, new Long(2));
		System.out.println("Employee get called");
		System.out.println("Employee ID= "+emp.getId());
		System.out.println("Employee Get Details:: "+emp+"\n");
		
		//Esempio di load
		Employee emp1 = (Employee) session.load(Employee.class, new Long(1));
		System.out.println("Employee load called");
		System.out.println("Employee ID= "+emp1.getId());
		System.out.println("Employee load Details:: "+emp1+"\n");
		
		//Chiudi risorse
		tx.commit();
		sessionFactory.close();
	}
}

Quando eseguo il codice sopra, produce il seguente output.

Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
Employee get called
Employee ID= 2
Employee Get Details:: Id= 2, Name= David, Salary= 200.0, {Address= AddressLine1= Arques Ave, City=Santa Clara, Zipcode=95051}

Employee load called
Employee ID= 1
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
Employee load Details:: Id= 1, Name= Pankaj, Salary= 100.0, {Address= AddressLine1= Albany Dr, City=San Jose, Zipcode=95129}

Dall’output è chiaro che get() restituisce l’oggetto recuperandolo dal database o dalla cache di Hibernate, mentre load() restituisce solo il riferimento di un oggetto che potrebbe non esistere effettivamente; carica i dati dal database o dalla cache solo quando si accede alle altre proprietà dell’oggetto. Ora proviamo a recuperare dati che non esistono nel database.

//Esempio di get
try{
Employee emp = (Employee) session.get(Employee.class, new Long(200));
System.out.println("Employee get called");
if(emp != null){
System.out.println("Employee GET ID= "+emp.getId());
System.out.println("Employee Get Details:: "+emp+"\n");
}
}catch(Exception e){
	e.printStackTrace();
}

//Esempio di load
try{
Employee emp1 = (Employee) session.load(Employee.class, new Long(100));
System.out.println("Employee load called");
System.out.println("Employee LOAD ID= "+emp1.getId());
System.out.println("Employee load Details:: "+emp1+"\n");
}catch(Exception e){
	e.printStackTrace();
}

Il codice sopra produce il seguente output.

Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
Employee get called
Employee load called
Employee LOAD ID= 100
Hibernate: select employee0_.emp_id as emp_id1_1_0_, employee0_.emp_name as emp_name2_1_0_, employee0_.emp_salary as emp_sala3_1_0_, address1_.emp_id as emp_id1_0_1_, address1_.address_line1 as address_2_0_1_, address1_.city as city3_0_1_, address1_.zipcode as zipcode4_0_1_ from EMPLOYEE employee0_ left outer join ADDRESS address1_ on employee0_.emp_id=address1_.emp_id where employee0_.emp_id=?
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.journaldev.hibernate.model.Employee#100]
	at org.hibernate.internal.SessionFactoryImpl$1$1.handleEntityNotFound(SessionFactoryImpl.java:253)
	at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:262)
	at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:176)
	at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286)
	at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
	at com.journaldev.hibernate.model.Employee_$$_jvst407_1.toString(Employee_$$_jvst407_1.java)
	at java.lang.String.valueOf(String.java:2847)
	at java.lang.StringBuilder.append(StringBuilder.java:128)
	at com.journaldev.hibernate.main.HibernateExample.main(HibernateExample.java:36)

Guarda attentamente l’output, quando usiamo get() per recuperare dati che non esistono, restituisce null. Ha senso perché cerca di caricare i dati non appena vengono chiamati. Con load(), siamo in grado di stampare l’id ma non appena proviamo ad accedere ad altri campi, scatena una query al database e genera org.hibernate.ObjectNotFoundException se non viene trovato alcun record con l’identificatore dato. È un’eccezione specifica di Hibernate Runtime Exception, quindi non è necessario catturarla esplicitamente. Diamo anche un’occhiata ad alcuni dei metodi sovraccaricati. I metodi get() e load() sopra potrebbero essere stati scritti anche come segue.

Employee emp = (Employee) session.get("com.journaldev.hibernate.model.Employee", new Long(2));

Employee emp1 = (Employee) session.load("com.journaldev.hibernate.model.Employee", new Long(1));

Employee emp2 = new Employee();
session.load(emp1, new Long(1));

Ci sono altri metodi con l’argomento LockOptions ma non li ho utilizzati. Nota che dobbiamo passare il nome completo della classe come argomento. Sulla base delle spiegazioni precedenti abbiamo le seguenti differenze tra get() vs load():

  1. get() carica i dati non appena viene chiamato mentre load() restituisce un oggetto proxy e carica i dati solo quando sono effettivamente richiesti, quindi load() è migliore perché supporta il caricamento pigro.
  2. Dato che load() genera un’eccezione quando i dati non vengono trovati, dovremmo usarlo solo quando sappiamo che i dati esistono.
  3. Dovremmo usare get() quando vogliamo assicurarci che i dati esistano nel database.

Questo è tutto per i metodi get e load di Hibernate, spero che chiarisca alcuni dubbi e ti aiuti a decidere quale utilizzare in diverse situazioni.

Source:
https://www.digitalocean.com/community/tutorials/hibernate-session-get-vs-load-difference-with-examples