Saturday, December 21, 2013

Different between session.get() and session.load()


There are two methods that can be used on a Hibernate session (org.hibernate.Session) to retrieve a single instance of persistent object. They are get( ) and load( ).

Note: In hibernate4.x there is one more method to get a single instance called byId(). See more details in below.



If load() can’t find the object in the cache or database, an exception is thrown. The load() method never returns null. The get() method returns null if the object can’t be found.
While the load() method will return a proxy (or the instance if already initialized), allowing lazy initialization and thus better performance. On the other hand, get() never returns a proxy. 

1. session.load()
  • Use this method if it is sure that the object exist
  • It always return proxy instead of a real persistent instance. A proxy is a placeholder that triggers the loading of the real object when it’s accessed for the first time.
  • If no row found , it will throws an ObjectNotFoundException.

methods:
load(Class clazz, Serializable id)
load(Class clazz, Serializable id, LockMode lockMode)
load(String className, Serializable id)
load(String className, Serializable id, LockMode lockMode)
load(Object object, Serializable id)

2. session.get()

  • Use this method if it is not sure that the object exist.
  • It always hit the database and return the real object, an object that represent the database row, not proxy.
  • If no row found , it return null.
 
methods:
get(Class clazz, Serializable id)
get(Class clazz, Serializable id, LockMode lockMode)
get(String className, Serializable id)
get(String className, Serializable id, LockMode lockMode)

Example:

Person.java
================================
package com.ranga.mapping;
import java.io.Serializable;
public class Person implements Serializable {
   
   private long id;
   private String firstName;
   private String lastName;
   private int age;
   
   public long getId() {
       return id;
   }
   public void setId(long id) {
       this.id = id;
   }
   public String getFirstName() {
       return firstName;
   }
   public void setFirstName(String firstName) {
       this.firstName = firstName;
   }
   public String getLastName() {
       return lastName;
   }
   public void setLastName(String lastName) {
       this.lastName = lastName;
   }
   public int getAge() {
       return age;
   }
   public void setAge(int age) {
       this.age = age;
   }
   @Override
   public String toString() {
       return "Person [id=" + id + ", firstName=" + firstName + ", lastName="
               + lastName + ", age=" + age + "]";
   }    
       
}

Person.hbm.xml
=======================
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.ranga.mapping">
   <class name="Person" table="Persons">
       <id name="id">
           <generator class="increment"/>               
       </id>
       <property name="firstName" />
       <property name="lastName" />
       <property name="age" />        
   </class>
</hibernate-mapping>

hibernate.cfg.xml
=============================
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
   <session-factory>
       <!-- Database connection settings -->
       <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
       <property name="connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>
       <property name="connection.username">ranga</property>
       <property name="connection.password">ranga</property>
       <!-- JDBC connection pool (use the built-in) -->
       <property name="connection.pool_size">1</property>
       <!-- SQL dialect -->
       <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
       <!-- Enable Hibernate's automatic session context management -->
       <property name="current_session_context_class">thread</property>
       <!-- Disable the second-level cache -->
       <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
       <!-- Echo all executed SQL to stdout -->
       <property name="show_sql">false</property>
       <!-- Drop and re-create the database schema on startup -->
       <property name="hbm2ddl.auto">create</property>
       <mapping resource="com/ranga/mapping/Person.hbm.xml" />
   </session-factory>
</hibernate-configuration>

App.java
======================
package com.ranga;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import com.ranga.mapping.Person;
import com.ranga.util.HibernateUtil;

public class App {
   public static void main(String[] args) {
       SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
       Session session = sessionFactory.openSession();
       session.beginTransaction();
       Person p1 = new Person();
       p1.setFirstName("ranga");
       p1.setLastName("reddy");
       p1.setAge(25);
       long pId = (Long) session.save(p1);
       session.getTransaction().commit();

       // get() method
       Person person = (Person) session.get(Person.class, pId);
       System.out.println(person);

       // load() method
       person = (Person) session.load(Person.class, pId);
       System.out.println(person);
       
       person = (Person) session.get(Person.class, 100l);
       System.out.println(person);

       // load() method
       person = (Person) session.load(Person.class, 100l);
       System.out.println(person);
       session.close();
   }
}

Output:

Person [id=1, firstName=ranga, lastName=reddy, age=25]
Person [id=1, firstName=ranga, lastName=reddy, age=25]
null
Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.ranga.mapping.Person#100]
------------------------------------------------------------------------------------------------------------------------

byId(): Hibernate4.x support one more method to retrieve a single instance i.e byId()

IdentifierLoadAccess byId(String entityName) - Create an IdentifierLoadAccess instance to retrieve the specified entity type by primary key.
IdentifierLoadAccess byId(Class entityClass) - Create an IdentifierLoadAccess instance to retrieve the specified entity by primary key.

Obtaining an entity reference without initializing its data:

Person person = (Person) session.byId(Person.class).getReference(personId);
System.out.println("By using byId() with reference: "+person);

Person person = (Person) session.byId(Person.class).getReference(100l);
System.out.println("By using byId() with reference: "+person);

Output:
By using byId() with reference: Person [id=1, firstName=ranga, lastName=reddy, age=25]
By using byId() with reference: Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.ranga.mapping.Person#100]

Obtaining an entity with its data initialized:

Person person = (Person) session.byId(Person.class).load(orderId);
System.out.println("By using byId() with load(): "+person);
       
Person person = (Person) session.byId(Person.class).load(100l);
System.out.println("By using byId() with load() "+person);

Output:
By using byId() with load(): Person [id=1, firstName=ranga, lastName=reddy, age=25]
By using byId() with load(): null

0 comments: