The difference between get and load in hibernate's delayed loading

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, and the other is through the session.load() method. In fact, these two methods are in There is a difference when getting an entity object, and the two are different in terms of query performance.

1. Load loading method

When using the load method to get an object, hibernate will use the lazy loading mechanism to load the object, that is: when we use the session.load() method to load an object, it is not The sql statement will be issued. The currently obtained object is actually a proxy object. This proxy object only saves the id value of the entity object. Only when we want to use this object and get other attributes, will the sql statement be issued at this time. To query our object in the database.


Java code Collection code

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

we see that if we just load our User object through load, we will find from the console that it will not be loaded from the console. The object is queried in the database, that is, the sql statement will not be issued, but if we want to use the object:




Java code Collection code

    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 a sql query statement, and the object will be queried from the database:




Sql code collection code

    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=? 

At this time, we may think, since calling load method, it will not issue a sql statement to find the object from the database, so what object is this User object?



In fact, this User object is one of our proxy objects. This proxy object only saves the id attribute:


Java code collection code

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

console output: 2



We see that if we only print out the id value of this user object At this time, the console will print out the id value, but also will not issue a sql statement to query from the database. This proves that our user object is just a proxy object that saves the id, but if I need to print out the values ​​of other attributes of the user object, will I issue a sql statement at this time? The answer is yes:


Java code collection code

    session = HibernateUtil.openSession(); 
               /*
                * When loading an object through load, the lazy loading mechanism will be used, and the User object obtained at this time is actually a
                * proxy object, the proxy object There is only the id attribute in it
                */ 
               User user = (User)session.load(User.class, 2); 
               System.out.println(user.getId()); 
               // If you want to get other user attributes at this time, then will query from the database 
               System.out.println(user.getUsername());           

console output:




Java code Favorite code

    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. Get loading method

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

3. Some small problems

when understanding the loading mechanism of load and get, let's take a look at some small problems that will appear in these two methods:

① If you use the get method to load objects, when we When trying to get an object whose id does not exist, NULL will be returned, and a NullPointException will be reported.







② If the object is loaded using the load method, when we try to get an object whose id does not exist, an ObjectNotFoundException will be reported:



Why use the load method and the get method to get an exception reported by a non-existent object different? ? The reason is because of the delay loading mechanism of load. When using load, the user object at this time is a proxy object, which only saves the current id value. When we try to get the username attribute of the object, this attribute does not exist. , so ObjectNotFoundException will be reported.

③org.hibernate.LazyInitializationException

Next , let's look at another example:


Java code Collection code

    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; 
        } 
    } 




Java代码  收藏代码

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

Simulate an object such as 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


Java code Collection code

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

What is the reason for this exception? ? Or because of the lazy loading mechanism of load, when we load an object through the load() method, no sql statement is issued to query the object from the database. The current object is just a proxy object with only an id. We The object has not been used yet, but our session has been closed at this time, so when we use the object in the test case, a LazyInitializationException will be reported.

So in the future, as long as we see an exception such as LazyInitializationException reported in the console, we know that an object is delayed by using the load method. There are two ways to solve this. One is to change the load to get to get the object. , the other is to open our session and close the session in the presentation layer.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326523961&siteId=291194637