A Sessão do Hibernate fornece diferentes métodos para buscar dados do banco de dados. Dois deles são – get() e load(). Também existem muitos métodos sobrecarregados para estes, que podemos usar em diferentes circunstâncias. À primeira vista, tanto get()
quanto load()
parecem similares porque ambos buscam os dados do banco de dados, no entanto, existem algumas diferenças entre eles, vamos analisá-las com um exemplo simples.
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) {
//Preparação
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
//Exemplo de 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");
//Exemplo de 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");
//Fechar recursos
tx.commit();
sessionFactory.close();
}
}
Ao executar o código acima, ele produz a seguinte saída.
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}
A partir da saída, fica claro que get()
retorna o objeto ao buscá-lo do banco de dados ou do cache do Hibernate, enquanto load()
apenas retorna a referência de um objeto que pode não existir realmente, ele carrega os dados do banco de dados ou do cache apenas quando você acessa outras propriedades do objeto. Agora, vamos tentar buscar dados que não existem no banco de dados.
//Exemplo de 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();
}
//Exemplo de 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();
}
O código acima produz a seguinte saída.
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)
Veja o resultado de perto, quando usamos get()
para recuperar dados que não existem, ele retorna null. Isso faz sentido porque tenta carregar os dados assim que é chamado. Com load()
, podemos imprimir o id, mas assim que tentamos acessar outros campos, ele dispara uma consulta ao banco de dados e lança org.hibernate.ObjectNotFoundException
se não houver registro encontrado com o identificador fornecido. É uma Exceção de Tempo de Execução específica do Hibernate, então não precisamos capturá-la explicitamente. Vamos dar uma olhada em alguns dos métodos sobrecarregados também. Os métodos get() e load() acima poderiam ter sido escritos como abaixo também.
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));
Há outros métodos com argumento LockOptions
, mas não os utilizei. Note que precisamos passar o nome completo da classe como argumento. Com base nas explicações acima, temos as seguintes diferenças entre get() vs load():
get()
carrega os dados assim que é chamado, enquantoload()
retorna um objeto de proxy e carrega os dados apenas quando realmente necessário, entãoload()
é melhor porque suporta carregamento preguiçoso.- Já que
load()
lança exceção quando os dados não são encontrados, devemos usá-lo apenas quando soubermos que os dados existem. - Devemos usar
get()
quando quisermos garantir que os dados existam no banco de dados.
Isso é tudo para os métodos get e load do Hibernate, espero que esclareça algumas dúvidas e ajude você a decidir qual usar em diferentes cenários.