فرق بين get() و load() في جلسة Hibernate مع أمثلة

جلسة هايبرنيت توفر أساليب مختلفة لاسترجاع البيانات من قاعدة البيانات. من بينها – get() و load(). هناك أيضًا العديد من الأساليب المتعددة لهذه الوظائف، التي يمكننا استخدامها في ظروف مختلفة. عند النظر الأولي يبدو كل من get() و load() متشابهين لأن كلاهما يسترجع البيانات من قاعدة البيانات، ومع ذلك هناك بعض الاختلافات بينهما، دعنا نلقي نظرة عليها من خلال مثال بسيط.

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) {
		
		//التحضير
		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		Session session = sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		
		//مثال 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");
		
		//مثال 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");
		
		//إغلاق الموارد
		tx.commit();
		sessionFactory.close();
	}
}

عند تنفيذ الشفرة أعلاه، ينتج الناتج التالي.

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}

من الناتج واضح أن get() يعيد الكائن عن طريق جلبه من قاعدة البيانات أو من ذاكرة التخزين المؤقت لهايبرنيت بينما load() يعيد فقط مرجعًا لكائن قد لا يكون موجودًا فعليًا، يتم تحميل البيانات من قاعدة البيانات أو الذاكرة المؤقتة فقط عند الوصول إلى خصائص أخرى للكائن. الآن دعنا نحاول استرجاع البيانات التي لا توجد في قاعدة البيانات.

//مثال 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();
}

//مثال 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();
}

تنتج الشفرة أعلاه الناتج التالي.

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)

انظر إلى الناتج بعناية، عند استخدام get() لاسترداد البيانات التي لا توجد، فإنه يعيد null. هذا منطقي لأنه يحاول تحميل البيانات بمجرد استدعائه. بالنسبة لـ load()، نحن قادرون على طباعة المعرف ولكن بمجرد محاولتنا الوصول إلى حقول أخرى، فإنه يُطلق استعلام قاعدة بيانات ويُلقي org.hibernate.ObjectNotFoundException إذا لم يتم العثور على سجل بالمعرف المعطى. إنه استثناء تشغيل محدد لـ هيبرنيت، لذا لا نحتاج إلى التقاطه بشكل صريح. دعونا نلقي نظرة على بعض الأساليب المحملة الزائدة أيضًا. يمكن كتابة الأساليب get() و load() كما يلي أيضًا.

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

هناك أساليب أخرى مع وسيطة LockOptions ولكنني لم أستخدمها. لاحظ أنه يجب علينا تمرير اسم الفئة الكامل كوسيطة. بناءً على التفسيرات أعلاه، لدينا الفروق التالية بين get() مقابل load():

  1. get() يحمل البيانات بمجرد استدعائه، بينما load() يعيد كائن بروكسي ويحمل البيانات فقط عندما يكون ذلك مطلوبًا فعليًا، لذا load() هو الأفضل لأنه يدعم التحميل الكسلي.
  2. نظرًا لأن load() يُلقي استثناء عندما لا توجد البيانات، يجب علينا استخدامه فقط عندما نعرف أن البيانات موجودة.
  3. يجب علينا استخدام get() عندما نريد التأكد من وجود البيانات في قاعدة البيانات.

هذا كل شيء بالنسبة لأساليب الحصول والتحميل في هيبرنيت، آمل أن يساعد ذلك في تفسير بعض الشكوك ويساعدك في اتخاذ القرار بشأن أيهما يجب استخدامه في سيناريوهات مختلفة.

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