La session Hibernate fournit différentes méthodes pour récupérer des données de la base de données. Deux d’entre elles sont – get() et load(). Il existe également de nombreuses méthodes surchargées pour celles-ci, que nous pouvons utiliser dans différentes circonstances. À première vue, get()
et load()
semblent similaires car elles récupèrent toutes deux les données de la base de données, cependant il y a quelques différences entre elles, regardons-les avec un exemple simple.
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) {
//Préparation
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
//Exemple de récupération
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");
//Exemple de chargement
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");
//Fermeture des ressources
tx.commit();
sessionFactory.close();
}
}
Lorsque j’exécute le code ci-dessus, il produit la sortie suivante.
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}
D’après la sortie, il est clair que get()
renvoie l’objet en le récupérant de la base de données ou du cache Hibernate tandis que load()
renvoie simplement la référence d’un objet qui pourrait ne pas exister réellement, il charge les données de la base de données ou du cache uniquement lorsque vous accédez à d’autres propriétés de l’objet. Maintenant, essayons de récupérer des données qui n’existent pas dans la base de données.
//Exemple de récupération
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();
}
//Exemple de chargement
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();
}
Le code ci-dessus produit la sortie suivante.
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)
Regardez de près la sortie, lorsque nous utilisons get()
pour récupérer des données qui n’existent pas, cela renvoie null. Cela a du sens car il essaie de charger les données dès qu’elles sont appelées. Avec load()
, nous pouvons imprimer l’identifiant, mais dès que nous essayons d’accéder à d’autres champs, cela déclenche une requête à la base de données et lance org.hibernate.ObjectNotFoundException
s’il n’y a aucun enregistrement trouvé avec l’identifiant donné. C’est une Exception d’exécution spécifique à Hibernate, donc nous n’avons pas besoin de l’attraper explicitement. Regardons également certaines des méthodes surchargées. Les méthodes get() et load() ci-dessus pourraient également être écrites comme suit.
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));
Il existe d’autres méthodes avec l’argument LockOptions
, mais je ne les ai pas utilisées. Remarquez que nous devons passer le nom de classe complet comme argument. Sur la base des explications ci-dessus, nous avons les différences suivantes entre get() vs load():
get()
charge les données dès qu’elles sont appelées, tandis queload()
renvoie un objet proxy et charge les données uniquement lorsqu’elles sont réellement nécessaires, doncload()
est meilleur car il prend en charge le chargement paresseux.- Puisque
load()
lance une exception lorsque les données ne sont pas trouvées, nous devrions l’utiliser uniquement lorsque nous savons que les données existent. - Nous devrions utiliser
get()
lorsque nous voulons nous assurer que les données existent dans la base de données.
C’est tout pour les méthodes de récupération et de chargement de Hibernate, j’espère que cela dissipera certains doutes et vous aidera à décider laquelle utiliser dans différents scénarios.