הפעלת הסשן מספקת שיטות שונות לאחזור נתונים ממסד הנתונים. שתיים מביניהן הן – 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
` אם אין רשומה עם המזהה הנתון. זו חריגה מסוג רץ בזמן הקשורה ל־Hibernate, ולכן אין צורך לתפוס אותה באופן ברור. בואו נסתכל על חלק מהשיטות המוטעמות יותר. מעלה של 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():
get()
טוען את הנתונים בעת שימוש, בעוד ש־load()
מחזיר אובייקט פרוקסי וטוען נתונים רק כאשר יש באמת צורך, לכןload()
הוא טוב יותר כי הוא תומך בטעינה עצמאית.- מכיוון ש־
load()
זורק חריגה כאשר הנתונים אינם נמצאים, עלינו להשתמש בו רק כאשר אנו יודעים שהנתונים קיימים. - עלינו להשתמש ב־
get()
כאשר אנו רוצים לוודא שהנתונים קיימים במסד הנתונים.
זו הכל בקשר לשיטות הקריאה של Hibernate, אני מקווה שזה יבהיר כמה ספקות ויסייע לך להחליט איזו מהן להשתמש בסצנאות שונות.