Principle and implementation of Hibernate lazy loading

  • 2020-05-07 19:44:24
  • OfStack

This article illustrates the principle and implementation of Hibernate lazy loading. Share with you for your reference, as follows:

To further optimize the performance of Hibernate, use:

The performance of Hibernate can be improved by lazy loading technology, management of data fetching strategy, and cache management.

Lazy loading (load)

Lazy loading (load) is one of the mechanisms that Hibernate provides for efficient program execution, which is created only when the data of the object is actually used.

Lazy loading process: lazy loading is implemented through the proxy (Proxy) mechanism. Hibernate retrieved from the database, when some one object data access to a collection of an object attribute values, or obtain a 1 when the object is associated with the other one, because there is no use the object data (except identifier), Hibernate is not the real data to be loaded from the database, but just as the object to create a proxy object to represent the object, the object of all attributes for the default value; Only create this real object when you really need to use its data, and actually load its data from the database.

When the load() method on Session is called to load an entity; When an entity is loaded by Session, the values of the collection attributes in that entity are lazily loaded. When an entity is loaded by Session, lazy loading is applied to another entity object that is single-ended associated with that entity

Turn off lazy loading: you can use the get() method when loading a single entity.

For collection properties in an entity, you can < set > . < bag > . < list > ...). Add the property lazy="false". When a single end is associated with another entity object, it can be configured in a mapping file < one-to-one > , < many-to-one > Add attribute lazy="false" note: one-to-one cannot have constrained=true (the resulting sql statement shows the foreign key), otherwise lazy loading will not work.

2. There are mainly several default cases of lazy loading in Hibernate:

The & # 8226; Lazy loading is used when the load() method on Session is called to load an entity.
The & # 8226; When an entity is loaded by Session, the values of the collection attributes in that entity are lazily loaded. (one - to - many)
The & # 8226; When Session loads an entity, lazy loading is applied to another entity object associated with the entity's single end (one-to-one, many-to-one).
The & # 8226; The difference between the second and third cases is that: in the second case, the method to cancel the delay loading is to set the lazy loading property lazy="false" after the set label of the mapping file of 1 side with set attribute. In the third case, lazy="false" is set after the many-to-one label in the multiparty mapping file that has one side of many-to-one.

Objects that can be lazily loaded are overwritten proxy objects. When the associated session is not closed, accessing the properties of these lazily loaded objects (except getId and getClass), hibernate initializes these proxies or initializes the proxy objects with Hibernate.initialize (proxy). When the associated session is closed, an exception occurs when the lazily loaded object is accessed again.

3. Fetching strategy (fetch)

Configure the "fetch policy" to directly affect the query performance of session's get() and load() methods.

Single-ended associated < many-to-one > < one-to_one > Grab strategy on:

You can add an fetch attribute to a mapping element that is associated with a single end. select: lazy loading; join: in the same select statement, the inner join is used to obtain the data of the object and the data of its associated object. At this time, the lazy load of the associated object fails.

Grab strategy on collection attributes:

select: lazy loading; join: use an inner join in the same select statement to get the associated collection of the other party. The lazy on the association set will fail. subselect: send another query statement or subquery fetch. This policy also works for HQL queries.

4. Lazy loading case study

Case 1: a single entity calls the load () method to cancel lazy loading


package com.hbsi.test;
import org.hibernate.Session;
import org.junit.Test;
import com.hbsi.domain.User;
import com.hbsi.utils.HibernateUtil;
publicclass TestLazy {
// test get () method ;get() Methods are always executed whether you use them or not sql statements 
@Test
publicvoid testGet(){
Session session = HibernateUtil.getSession();
User user = (User) session.get(User.class,1);
// System.out.println(user.getName());
HibernateUtil.close();
// Here's the thing: even if it's closed session To make user In a managed state, it can still be used user object ; This is because although it is in a managed state, this object is an object with a property value, it is not deleted, it just cuts off its access to the database. 
System.out.println(user.getName());
}
// test load() Methods; Does not perform sql Statement, not executed until used 
@Test
publicvoid testLoad(){
Session session = HibernateUtil.getSession();
User user = (User) session.load(User.class,1);
// Here is the output id They don't execute sql Statement, which you passed directly from the top id To derive id , is not looked up from the database, so it is not executed sql statements 
System.out.println(user.getId());
// While the output name Don't 1 Sample, in this case is actually instantiating the proxy object, which is the proxy object name Property, even if you turn it off session , can also be obtained through this object name ; If this sentence is commented, the proxy object is not instantiated and is closed session Post execution output name Attribute, and an error is reported: could not initialize proxy
// System.out.println(user.getName());
HibernateUtil.close();
System.out.println(user.getName());
}
}

Case 2: lazy loading is unloaded on the set collection

If the lazy load in the collection properties is set to false in the mapping file, the test will be pulled out along with a block of data in the orders table, that is, two select statements


@Test
publicvoid find(){
Session session = HibernateUtil.getSession();
Customer cus = (Customer) session.get(Customer.class,3);
System.out.println(cus.getCname());
// The output will appear for two days using the following method sql Statement, and it's separate ; If you use lazy loading you'll get two output first sql Statement in the output result 
// There is no direct method chained output here cus.getOrd().getOname() ; because cus.getOrd() Returns the 1 a set A collection of 
Set<Orders> orders = cus.getOrd();
System.err.println(orders.size());
HibernateUtil.close();
}

Method 3: < one-to-one > , < many-to-one > Unlazy loading


@Test
publicvoid find(){
// Lazy loading is used by default 1 article sql Statement output 1 article ; If the delay load is set to false After output two sql Statement, will not need to find out the customer information 
Session session = HibernateUtil.getSession();
Orders ord = (Orders) session.get(Orders.class,3);
System.out.println(ord.getOname());
HibernateUtil.close();
}

I hope this article is helpful for you to design Java program based on Hibernate framework.


Related articles: