What is hibernate lazy loading? When do you use lazy loading? Why should I use lazy loading?

Source: Internet
Author: User
Tags set set

Lazy loading is delayed loading and delay loading.

When to load with lazy, I can only answer to lazy loading with lazy loading.

As for why lazy loading, is when we want to access the amount of data is too large, obviously with the cache is not appropriate,

Because the memory capacity is limited, in order to reduce the concurrency, reduce the consumption of system resources,

We let the data load when we needed it, and then we used lazy loading.

For example, Department entity and employee entity, Department and employee 1 to many, if lazy set to false, then as long as the loading of a department of PO, will be based on a one-to-many configuration of the relationship of all employees to the PO also loaded out. But in fact sometimes just need to use the Department of Information, do not need to use the information of employees, when the employee PO loading is tantamount to wasting resources. If lazy is set to true, only the information of the employee's PO will be loaded back when you access the employee information for the department PO.

hibernate3.0 in lazy has three values, True,false,proxy, the default is lazy= "proxy".
The specifics of what to look for depends on your needs, not which settings are the best.
If you include a Head object in a student object
If you are sure that you want to use the student object with the properties of the head object, then you set the load immediately, because the settings are loaded immediately then query student at the same time will query student head, Hibernate will correlate two tables at query time, resulting in only one SQL. And if you set a lazy load, then you will certainly generate 1+N SQL statements: where "1" is the statement of query student, "N" is based on the ID of N student to query the head of the N statement. And, lazy loading is to use the time to execute the query, so that the system to determine the need to load, there is no need to load and need time, performance is certainly not as immediately loaded!
If you are in a place where you need to use the student to use the head attribute, then you set it to lazy loading, because querying 2 tables of data is definitely more expensive than querying 1 tables.
How to set it down depends on your actual needs.

The lazy load mechanism is proposed to avoid some unnecessary performance overhead, so-called lazy loading is when the data is really needed to perform the data loading operation. Lazy loading of entity objects and lazy loading of collections are provided in Hibernate, and lazy loading of properties is also provided in Hibernate3.
A, lazy loading of entity objects
If you want to use lazy loading on an entity object, you must configure it in the entity's mapping configuration file as follows:
<class name= "Com.neusoft.entity.User" table= "User" lazy= "true" >
......
</class>
Turn on the lazy-load attribute of the entity by setting the class's Lazy property to true. If we run the following code:
User user= (user) Session.load (user.class, "1"); (1)
System.out.println (User.getname ()); (2)
When running to (1), Hibernate does not initiate a query of the data, if at this time through some debugging tools, observing the memory snapshot of the user object at this time, will be surprised to find that this time, the return may be user$enhancerbycglib$ $bede 8986 types of objects , and its property is null, what's going on? The Session.load () method returns the proxy class object for the entity object, and the object type returned here is the proxy class object for the user object. In Hibernate, a proxy class object that dynamically constructs a target object is implemented by using CGLIB, and all properties and methods of the target object are included in the proxy class object, and all properties are assigned null. The memory snapshot shown by the debugger shows that the real user object at this point is contained in the Cglib$calback_0.target property of the proxy object, and when the code runs to (2), the User.getname () method is called. At this point the callback mechanism given by Cglib actually calls the Cglib$calback_0.getname () method, and when the method is called, Hibernate first checks whether the Cglib$calback_0.target property is null, if not NULL, The GetName method of the target object is called, and if it is empty, a database query is initiated, generating a SQL statement like this: SELECT * from user where id= ' 1 ', to query the data, construct the target object, and assign it to cglib$calback_0. The target property.
In this way, hibernate implements lazy loading of entities through an intermediary proxy object, and the database query operation is really initiated only when the user actually initiates an action that obtains the attributes of the entity object. So the lazy loading of the entity is done through the intermediate proxy class, so only the Session.load () method takes advantage of entity lazy loading, because only the Session.load () method returns the proxy class object of the entity class.
B, deferred loading of collection types
In Hibernate's lazy loading mechanism, the significance of the application for the collection type is most significant, as this has the potential to significantly improve performance, and this is a great effort for hibernate, including a standalone implementation of the JDK collection, in a one-to-many association, The set set that is defined to hold the associated object, not the Java.util.Set type or its subtypes, but Net.sf.hibernate.collection.Set types, Hibernate implements deferred loading of collection types by using the implementation of custom collection classes. In order to use lazy loading for a collection type, you must configure the associated part of the entity class as follows:
<class name= "Com.neusoft.entity.User" table= "User" >
......
<set name= "Addresses" table= "Address" lazy= "true" inverse= "true" >
<key column= "user_id"/>
<one-to-many class= "Com.neusoft.entity.Arrderss"/>
</set>
</class>
Turn on the lazy-load attribute of the collection type by setting the <set> element's lazily property to true. Look at the following code:
User user= (user) Session.load (user.class, "1");
Collection addset=user.getaddresses (); (1)
Iterator It=addset.iterator (); (2)
while (It.hasnext ()) {
Address address= (address) it.next ();
System.out.println (Address.getaddress ());
}
When the program executes to (1), it does not initiate a query to the associated data to load the associated data, and when it runs to (2), the actual data read operation starts, and Hibernate finds the qualifying entity object based on the data index that matches the criteria in the cache.
Here is a new concept-the data index, which first describes what the data index is. When a collection type is cached in Hibernate, it is cached in two parts, first caching the list of IDs for all entities in the collection, and then caching the entity objects, which are the so-called data indexes. When looking for a data index, if no corresponding data index is found, a select SQL is executed, the data is matched, the entity object collection and the data index are constructed, the collection of entity objects is returned, and the entity object and the data index are included in Hibernate's cache. On the other hand, if the corresponding data index is found, the list of IDs is taken from the data index, and the corresponding entity is found in the cache based on the ID, if it is returned from the cache, if it is not found, the Select SQL query is initiated. Here we see another problem, which can have an impact on performance, which is the cache strategy for the collection type. If you configure the collection type as follows:
<class name= "Com.neusoft.entity.User" table= "User" >
...
<set name= "Addresses" table= "Address" lazy= "true" inverse= "true" >
<cache usage= "Read-only"/>
<key column= "user_id"/>
<one-to-many class= "Com.neusoft.entity.Arrderss"/>
</set>
</class>
The <cache usage= "read-only"/> Configuration is applied, and if this policy is used to configure the collection type, hibernate will only cache the data index, not the entity objects in the collection. Run the following code as configured above:
User user= (user) Session.load (user.class, "1");
Collection addset=user.getaddresses ();
Iterator It=addset.iterator ();
while (It.hasnext ()) {
Address address= (address) it.next ();
System.out.println (Address.getaddress ());
}
SYSTEM.OUT.PRINTLN ("Second query ...");
User user2= (user) Session.load (user.class, "1");
Collection it2=user2.getaddresses ();
while (It2.hasnext ()) {
Address address2= (address) it2.next ();
System.out.println (Address2.getaddress ());
}

Running this code will give you output similar to the following:
Select * from user where id= ' 1 ';
Select * FROM address where user_id= ' 1 ';
Tianjin
Dalian
Second query ...
Select * FROM address where id= ' 1 ';
Select * FROM address where id= ' 2 ';
Tianjin
Dalian
As you can see, when you execute a query for the second time, you execute two query operations on the Address table. This is because when the entity is loaded for the first time, based on the configuration of the collection type cache policy, the collection data index is cached only, and the entity objects in the collection are not cached, so hibernate finds the data index of the corresponding entity when the entity is reloaded the second time, but according to the data index, Instead of finding the corresponding entity in the cache, hibernate initiated two select SQL query operations based on the data index found, which creates a waste of performance and how can you avoid this situation? You must also specify a cache policy for the entities in the collection type and configure the collection type:
<class name= "Com.neusoft.entity.User" table= "User" >
......
<set name= "Addresses" table= "Address" lazy= "true" inverse= "true" >
<cache usage= "Read-write"/>
<key column= "user_id"/>
<one-to-many class= "Com.neusoft.entity.Arrderss"/>
</set>
</class>
Hibernate will also cache the entities in the collection type and run the above code again, and you will get output similar to the following:
Select * from user where id= ' 1 ';
Select * FROM address where user_id= ' 1 ';
Tianjin
Dalian
Second query ...
Tianjin
Dalian
There will be no more SQL statements to query against the data index, because entity objects stored in the collection type can be obtained directly from the cache at this time.
C, property lazy Loading
In Hibernate3, a new feature-deferred loading of attributes is introduced, which provides a powerful tool for obtaining high-performance queries. When reading large data objects, it is assumed that there is a resume field in the user object that is a Java.sql.Clob type that contains the user's CV information, which must be loaded every time the object is loaded, whether or not it is really needed. And the reading of this big data object can have a significant performance overhead. In Hibernate2, it is only possible to solve this problem by decomposing the user class with performance-oriented granularity, but in Hibernate3, we can get the ability to read this field data only when we really need to manipulate this field, in the case of a property delay loading mechanism. To do this, you must configure the entity class as follows:
<class name= "Com.neusoft.entity.User" table= "User" >
......
<property name= "Resume" type= "Java.sql.Clob" column= "Resume" lazy= "true"/>
</class>
By setting true for the lazy property of the <property> element to enable lazy loading of the property, the class enhancer is used to harden the classes of the entity classes in Hibernate3 in order to implement deferred loading of the attributes, which is enhanced by the enhancer. The cglib callback mechanism logic is added to the entity class, where we can see the deferred loading of the properties, or the implementation through Cglib. Cglib is an open source project for Apache, which can manipulate the bytecode of Java classes and dynamically construct class objects that meet the requirements based on bytecode. According to the above configuration we run the following code:
String sql= "from user user where user.name= ' ZX '";
Query query=session.createquery (SQL); (1)
List list=query.list ();
for (int i=0;i<list.size (); i++) {
User user= (user) list.get (i);
System.out.println (User.getname ());
System.out.println (User.getresume ()); (2)
}
When executed to (1), a SQL statement similar to the following is generated:
Select id,age,name from user where name= ' ZX ';
Hibernate retrieves the field data for all non-lazy load properties in the user entity, and when it executes to (2), a SQL statement similar to the following is generated:
Select resume from user where id= ' 1 ';
A real read operation is initiated for the Resume field data.

What is hibernate lazy loading? When do you use lazy loading? Why should I use lazy loading?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.