웹사이트 검색

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() 사이에 다음과 같은 차이점이 있습니다.

  1. get()은 호출되는 즉시 데이터를 로드하는 반면 load()는 프록시 객체를 반환하고 실제로 필요할 때만 데이터를 로드하므로 로드()는 지연 로딩을 지원하기 때문에 더 좋습니다.
  2. load()는 데이터를 찾을 수 없을 때 예외를 발생시키므로 데이터가 존재한다는 것을 알고 있을 때만 사용해야 합니다.
  3. 데이터베이스에 데이터가 있는지 확인하려면 get()을 사용해야 합니다.

이것이 최대 절전 모드 가져오기 및 로드 방법에 대한 전부입니다. 이것이 몇 가지 의심을 없애고 다른 시나리오에서 사용할 방법을 결정하는 데 도움이 되기를 바랍니다.