Hibernate 세션 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) {
//Prep Work
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
//Get Example
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 Example
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");
//Close resources
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 Example
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 Example
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()
를 사용하면 ID를 인쇄할 수 있지만 다른 필드에 액세스하려고 시도하는 즉시 데이터베이스 쿼리를 실행하고 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() 사이에 다음과 같은 차이점이 있습니다.
get()
은 호출되는 즉시 데이터를 로드하는 반면load()
는 프록시 객체를 반환하고 실제로 필요할 때만 데이터를 로드하므로로드()
는 지연 로딩을 지원하기 때문에 더 좋습니다.load()
는 데이터를 찾을 수 없을 때 예외를 발생시키므로 데이터가 존재한다는 것을 알고 있을 때만 사용해야 합니다.- 데이터베이스에 데이터가 있는지 확인하려면
get()
을 사용해야 합니다.
이것이 최대 절전 모드 가져오기 및 로드 방법에 대한 전부입니다. 이것이 몇 가지 의심을 없애고 다른 시나리오에서 사용할 방법을 결정하는 데 도움이 되기를 바랍니다.