get and load queries in Hibernate Framework

Posted by NZ_Kiwis on Sun, 05 Apr 2020 22:37:01 +0200

Original link: http://www.yiidian.com/hibernate/hibernate-get-load.html

1. Demonstrate the basic use of get and load methods

/**
 * Show basic object query
 * @author http://www.yiidian.com
 *
 */
public class Demo {

	/**
	 * get()Method: query an object
	 */
	@Test
	public void test1(){
		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		
		Customer cust = session.get(Customer.class,1);
		Set<Order> orders = cust.getOrders();
		System.out.println(cust.getName()+"Order:");
		for (Order order : orders) {
			System.out.println(order.getOrderno());
		}
		
		tx.commit();
		session.close();
	}
	
	/**
	 * load()Method: query an object
	 */
	@Test
	public void test2(){
		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		
		Customer cust = session.load(Customer.class,1);
		Set<Order> orders = cust.getOrders();
		System.out.println(cust.getName()+"Order:");
		for (Order order : orders) {
			System.out.println(order.getOrderno());
		}
		
		tx.commit();
		session.close();
	}
}

Source code download: https://pan.baidu.com/s/1c2HD7tm

2. Analyze the difference between get and load methods

In hibernate, we know that if we want to get an object from the database, there are usually two ways, one is through the session.get() method, the other is through the session.load() method, and in fact, these two methods are different when we get an entity object, and they are different in query performance.

2.1 load mode

When using the load method to get an object, hibernate will use the delayed loading mechanism to load the object, that is, when we use the session.load() method to load an object, no sql statement will be issued at this time. The current object is actually a proxy object, which only stores the id value of the entity object. Only when we want to make When we use this object to get other properties, we will issue sql statements to query our objects from the database.    

session = HibernateUtil.openSession();
/*
 * When loading objects by load, the delayed loading mechanism will be used. At this time, no sql statement will be issued. Only when we need to use it, can we query from the database
*/
User user = (User)session.load(User.class, 2);

We can see that if we only load our User object through load, then from the console we will find that we will not query the object from the database, that is, sql statement will not be issued, but if we want to use the object:

session = HibernateUtil.openSession();
User user = (User)session.load(User.class, 2);
System.out.println(user);

At this point, we see that the console will issue an sql query statement, which will query the object from the database:

Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.password as password0_0_, user0_.born as born0_0_ from user user0_ where user0_.id=?
User [id=2, username=aaa, password=111, born=2013-10-16 00:14:24.0]

At this time, we may think that since the load method is called, it does not issue sql statements to find out the object from the database, what object is the User object?

In fact, this User object is our proxy object. This proxy object only holds the attribute id:

session = HibernateUtil.openSession();
/*
* When loading objects by load, the delayed loading mechanism will be used. The User object obtained at this time is actually a
* Proxy object. Only the id attribute is in the proxy object
*/
User user = (User)session.load(User.class, 2);
System.out.println(user.getId());

We can see that if we only print the id value of the user object, the console will print the id value, but it will not issue sql statements to query from the database. This proves that our user object is just a proxy object with id saved. But if I need to print out other attribute values of the user object, will sql statement be issued at this time? The answer is yes:

session = HibernateUtil.openSession();
/*
* When loading objects by load, the delayed loading mechanism will be used. The User object obtained at this time is actually a
* Proxy object. Only the id attribute is in the proxy object
*/
User user = (User)session.load(User.class, 2);
System.out.println(user.getId());
// If you want to get other user properties at this time, you will query from the database
System.out.println(user.getUsername());   

Now let's look at the output of the console:

2
Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.password as password0_0_, user0_.born as born0_0_ from user user0_ where user0_.id=?
aaa

I believe that through the above examples, you should have a good understanding of the load method of loading objects.

2.2 get loading method

Compared with the delayed load method of load, get is more direct. When we use the session.get() method to get an object, whether we use this object or not, we will issue an sql statement to query from the database:

session = HibernateUtil.openSession();
/*
* When an object is loaded through the get method, whether or not the object is used, an sql statement will be issued to query from the database
*/
User user = (User)session.get(User.class, 2);

At this time, we get the user object through get, but we do not use it. However, we find that the console will output sql query statements:

Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.password as password0_0_, user0_.born as born0_0_ from user user0_ where user0_.id=?

Therefore, we can see that the load method using load has better performance than the load method using get, because when load is loaded, all you get is a proxy object. When you really need to use this object, you can query from the database.

2.3 small problems in using get and load

After understanding the loading mechanism of load and get, let's take a look at some small problems in these two ways:

① If the get method is used to load the object, when we try to get an object whose id does not exist, an exception of NullPointException will be reported

session = HibernateUtil.openSession();
/*
* When trying to get a user object with no id through get, a NullPointException exception will be reported
*/
User user = (User)session.get(User.class, 20);
System.out.println(user.getUsername());

At this time, when we look at the output information of the console, an exception of null pointer will be reported:

Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.password as password0_0_, user0_.born as born0_0_ from user user0_ where user0_.id=?
java.lang.NullPointerException  .........

This is because we will go to the database to find the object through get, but the id value does not exist, so the user object is null at this time, so an exception of NullPointException will be reported.

② If we use the load method to load objects, when we try to get an object whose id does not exist, an ObjectNotFoundException exception will be reported:

session = HibernateUtil.openSession();
/*
* When an attempt is made to get a user object whose id does not exist through get, an ObjectNotFoundException exception will be reported
*/
User user = (User)session.load(User.class, 20);
System.out.println(user.getId());
System.out.println(user.getUsername());

Let's look at the output of the console:

20
Hibernate: select user0_.id as id0_0_, user0_.username as username0_0_, user0_.password as password0_0_, user0_.born as born0_0_ from user user0_ where user0_.id=?
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.yiidian.bean.User#20]......

Why is it different to use the load method and get method to get an exception reported by a nonexistent object?? The reason is also because of the delayed loading mechanism of load. When load is used, the user object is a proxy object. Only the current id value is saved. When we try to get the username property of the object, the property does not exist, so the exception ObjectNotFoundException will be reported.

③ org.hibernate.LazyInitializationException

Let's take another example:

public class UserDAO
{
    public User loadUser(int id)
    {
        Session session = null;
        Transaction tx = null;
        User user =  null;
        try
        {
            session = HibernateUtil.openSession();
            tx = session.beginTransaction();
            user = (User)session.load(User.class, 1);
            tx.commit();
        }
        catch (Exception e)
        {
            e.printStackTrace();
            tx.rollback();
        }
        finally
        {
            HibernateUtil.close(session);
        }
        return user;
    }
}
 

@Test
public void testLazy06(){
        UserDAO userDAO = new UserDAO();
        User user = userDAO.loadUser(2);
        System.out.println(user);
}

We simulate an object like UserDAO, and then we load an object through load in the test case. At this time, we find that the console will report LazyInitializationException exception

org.hibernate.LazyInitializationException: could not initialize proxy - no Session  .............

What's the reason for this abnormality?? It's also because of the load delay loading mechanism. When we load an object through the load() method, no sql statement is issued to query the object from the database. Currently, the object is only an agent object with only id. we haven't used the object yet, but our session has been closed at this time. Therefore, when we use the This exception, LazyInitializationException, will be reported in the event of.

So in the future, as long as we see the console report LazyInitializationException, we will know that load is used to delay loading an object. There are two ways to solve this problem: one is to change load to get to get the object, the other is to open our session and close the session at the table display layer.

Welcome to my official account: a little tutorial. Get exclusive learning resources and daily dry goods push.
If you are interested in my series of tutorials, you can also follow my website: yiidian.com

Topics: Java Session Database Hibernate SQL