Hibernate get() vs load() Methods

Learn the difference between get() vs load() methods to fetch entity by id from the database using Hibernate.

In hibernate, load() always return a “proxy” object without hitting the database and get() always return the real object after fetching from the database,

1. Using Session.load() API

Hibernate’s Session interface provides several overloaded load() methods for loading entities from the database. Each load() method requires the object’s primary key as an identifier, and it is mandatory to provide it.

In addition to the ID, hibernate also needs to know which class or entity name to use to find the object with that ID. After the load() method returns, we need to cast the returned object to a suitable type of class to further use it. It’s all that load() method needs from us to work correctly.

Let’s look at different flavors of load() method available in hibernate Session interface.

public Object load(Class clazz, Serializable id) throws HibernateException
public Object load(String entityName, Serializable id) throws HibernateException
public void load(Object object, Serializable id) throws HibernateException
  1. The first method needs the Class type which we would like to load along with the primary key.
  2. The second method asks for entityName and the primary id. Both methods return the populated entity object as a return value which we will cast to the desired type.
  3. The third takes an object as an argument. The object should be of the same class as the object we would like loaded, and it should be empty. Hibernate will populate that object with the information we requested.

The other load() methods available through hibernate session take a lock mode as an argument too. The lock mode specifies whether Hibernate should look into the cache for the object and which database lock level Hibernate should use for the row (or rows) of data that represent this object.

In the official documentation, hibernate developers claim that Hibernate will usually pick the correct lock mode for us, although in some situations it is important to manually choose the correct lock.

Let’s look at the examples of each loading method in the simplest form to be clear about what we read above.

Long id = 1001; //An employee's primary id

//1
EmployeeEntity entity = (EmployeeEntity) 
	session.load(EmployeeEntity.class, id);

//2
EmployeeEntity entity = (EmployeeEntity) 
	session.load("com.howtodoinjava.demo.entity.EmployeeEntity", id);

//3
EmployeeEntity entity = new EmployeeEntity();
session.load(entity , id);

2. Using Session.get() API

The get() method is very much similar to load() method. The get() methods take an identifier, and either an entity name or a class types.

There are also two more get() methods that take a lock mode as an argument.

public Object get(Class clazz, Serializable id) throws HibernateException
public Object get(String entityName, Serializable id) throws HibernateException

There is not much difference in code while working with either load() or get() method, all you need is to replace the load() method with get() method in the first two examples. There is no get() equivalent to last load() method.

Long id = 1001; //An employee's primary id

//1
EmployeeEntity entity = (EmployeeEntity) 
	session.get(EmployeeEntity.class, id);

//2
EmployeeEntity entity = (EmployeeEntity) 
	session.get("com.howtodoinjava.demo.entity.EmployeeEntity", id);

3. Difference between load() and get() Methods

Why do we have two methods to do the same job. Actually, this is a frequently asked interview question as well.

The difference between get() and load() methods lies in the return value when the identifier does not exist in the database.

  1. The entity loaded with get() method is eager loaded and contains information from the database. Whereas the entity loaded from load() method is a lazy load proxy object that queries the database when any field information is accessed.
  2. In case of get() method, we will get the return value as NULL if the identifier is absent. But in the case of load() method, we will get ObjectNotFoundException.

The exception in the case of the load() method will look like this:

Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists:
[com.howtodoinjava.demo.entity.EmployeeEntity#23]
at org.hibernate.internal.SessionFactoryImpl$1$1.handleEntityNotFound(SessionFactoryImpl.java:253)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219)
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:275)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:151)
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1070)
	at org.hibernate.internal.SessionImpl.load(SessionImpl.java:940

4. Conclusion

In this hibernate tutorial, we learned the basics of load() and get() methods to fetch entity information from the database. We also learned the differences between both methods.

Happy Learning !!

Was this post helpful?

Join 7000+ Awesome Developers

Get the latest updates from industry, awesome resources, blog updates and much more.

* We do not spam !!

11 thoughts on “Hibernate get() vs load() Methods”

  1. Hi Lokesh,
    Many online tutorials say “get() method always hits the db”.
    but i dont see in the console the query triggered again if use get() twice.
    how far is this statement true?

    Reply
  2. short code | Stuatus | A(Sample2) | B(Sample2) | C(Sample2) | DSample2) | E (Sample2) | A(All Sample3) |
    11111 pending New New New New New New
    22222 under process New – New New –

    In the above Sample format it may helps for you (A,B,C under Sample1)(C,D are under Sample2),(A is the Sample3.The Sample3 have some status but here we are showing only on Carrier Staus that is the Default Status and some where i mentioned (‘-‘) that means the status we didn’t selected and observe for same alsi Sample3(‘-‘) but here i already select some status(b,c,d..) status except “A” But still it is showing the blank value.My question is inplace of bydefault status i want to display the status whatever we selected.I hope you understand.

    Reply
  3. Hi,

    I created one report.In reports there are three samples.sample1,sample2,sample3.When I run the report it is generated the XML.In that XML it will display all the Sample reports Status’s.But my question is in Sample1,Sample2,Sample3 there are some carriers list with check boxes .For example assume in Sample3 have some Carrier status with the names of A,B,C and so on.. with check boxes.First Carrier Status is by default i.e (“A”) and it is coming from DB remaining all are optional. When I am selecting the first Carrier Status in the generated XML the Carrier status is showing properly which we are selected that is fine.But the problem is when I selected all the Carrier(“b”,”c”..so on) except first Carrier (“A”) in the XML it is not showing the selected Carrier Status..Can you please tell me how to resolve this.Here is the Sample code.here Sample3CarrierNameList is Sample3 list i.e(a,b,c..) ,carrier means single carrier name(“a”…)

    for (Object resultRow : returnList) {
    Object[] rowResultSet = (Object[]) resultRow;

    Map rowMap = new LinkedHashMap();

    // rowMap.put(“reqProvisioningId”, rowResultSet[0].toString());
    rowMap.put(“reqDescription”, rowResultSet[0].toString());
    rowMap.put(“reqShortCode”, (String) rowResultSet[1]);
    rowMap.put(“reqStatusText”, (String) rowResultSet[2]);
    rowMap.put(“reqAssignedToInternal”, (String) rowResultSet[3]);
    int index = 4;

    //CMP 1.2 Upgrade. Fix for “Carrier Status of Requests For Customer” report
    //not displaying all tier 3 carrier status when carrier’s are renamed.
    boolean isTier3Populated = false;
    for (String carrier : carrierNameList) {

    // Now add the first Sample 3 Carrier as a representative of all
    // other Carriers
    if (isSample3Populated == false
    && Sample3CarrierNameList.size() > 0
    && Sample3CarrierNameList.contains(carrier)) {
    rowMap.put(Constants.ALL_TIER_3_CARRIER,
    (String) rowResultSet[index]);
    index++;
    isTier3Populated = true;
    } else if (!Sample3CarrierNameList.contains(carrier)) { // Exclude all Tier 3 Carriers Except the First One
    rowMap.put(carrier, (String) rowResultSet[index]);
    index++;
    }

    }

    carrierWiseList.add(rowMap);
    }

    logger.debug(“Carrier wise List:” + carrierWiseList);
    return carrierWiseList;
    }

    Thanks
    Sri.K

    Reply
  4. Hi LOkesh, good tutorial, can you help with this little problem?
    I hava a CategoryDao class and it has a getCategory() method to fetch a Category by ID. (This method works)

    @Override
    	public Category getById(int id) {
    		return (Category) sessionFactory.getCurrentSession().get(Category.class, id);
    	}
    

    And I need a same method to fetch a Category by its name, so I create a getByName() method but I have the following error:
    org.hibernate.TypeMismatchException: Provided id of the wrong type for class com.sedae.model.Category. Expected: class java.lang.Integer, got class java.lang.String.
    My method to fetch by name is as follow:

    @Override
    	public Category getByName(String name) {
    		return (Category) sessionFactory.getCurrentSession().get(Category.class, name);
    	}
    

    Can you show me where is my error? Thanks in advance…

    Reply
    • You can’t use any other attribute except primary key… Whether you wan’t to use another attribute you should have to use ‘HQL’.
      Also look at @naturalId…

      Something like

      sql query = “SELECT * FROM Category c where c.name= :name”

      and set the parameter like
      setParameter(“name”,parameterName)

      and get the result with getResultList or getSingleResult (if you are sure that query returns only one record)

      Reply

Leave a Comment

HowToDoInJava

A blog about Java and related technologies, the best practices, algorithms, and interview questions.