Hibernate3 Delay loading mechanism

Source: Internet
Author: User
Deferred loading: first of all, Hibernate3 delay loading only a number of load,get,find some of the internal value methods useful, for HQL, such as the invalid write SQL.    The delay loading mechanism is to avoid some unnecessary performance overhead, the so-called delay loading is when the real need for data, the real implementation of data loading operations. In the Hibernate provides deferred loading of entity objects and deferred loading of the collection, in addition to the Hibernate3 a deferred load on a property is also provided in. Let's go through the details of these kinds of deferred loading separately. A, deferred loading of entity objects: If you want to use deferred loading on entity objects, you must configure them in the mapping configuration file for the entity, as follows: <class name= "Com.neusoft.entity.User" table= "User" lazy= "true" > ..... </class> by putting class of the Lazy property is set to true to open the deferred loading attribute of the entity. If we run the following code: user user= (user) Session.load (user.class, "1"); ( 1 ) System.out.println (User.getname ()); ( 2 ) when you run to (1) Place, Hibernate no queries have been initiated on the data, if we pass some debugging tools at this time ( like JBuilder2005 of the Debug Tools ) , observe this time User The memory snapshot of the object, we will be surprised to find that at this time the return may be user$enhancerbycglib$ $bede 8986 The object of the type, and its properties are NULL, What's going on here. Remember when I told you before session.load () method returns the proxy class object for the entity object, and the object type returned here is User the proxy class object for the object. In the Hibernate by using the Cglib, to implement a proxy class object that dynamically constructs a target object, and contains all the properties and methods of the target object in the proxy class object, and all attributes are assigned to NULL . With the memory snapshot shown by the debugger, we can see that at this point the real User object that is contained in the proxy object. Cglib$calback_0.target property, when the code runs to ( 2 ) is called at this time. User.getname () method at this time by Cglib Given the callback mechanism that actually calls the Cglib$calback_0.getname () method, when the method is called, Hibernate will first check Cglib$calback_0.target whether the property is NULL , if not NULL, the target object's GetName method, if it is empty, a database query is initiated to generate a similar SQL statement: SELECT * from user where id= ' 1 '; to query the data and construct the target object, and assign it to the Cglib$calback_0.target property.    so, through an intermediate proxy object, Hibernate implement the delay loading of the entity, only when the user really initiates the action of obtaining the attributes of the entity object, the database query operation is really initiated. So the delay loading of the entity is done through the intermediate proxy class, so only session.load () method to use entity delay loading because only session.load () method returns the proxy class object for the entity class. B, deferred loading of collection types: in the Hibernate delay loading mechanism, for the application of the set type, the significance is the most important, because it is possible to greatly improve performance, so Hibernate A great deal of effort has been made, including the JDK Collection In a One-to-many association, defined to hold the associated object Set collection, not Java.util.Set type or its subtypes, but rather Net.sf.hibernate.collection.Set type, by using the implementation of the custom collection class , Hibernate deferred loading of the collection type was implemented. In order to use deferred loading for the collection type, we must configure the associated part of our 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> by putting <set> Elements of Lazy property is set to true to open the deferred load attribute of the collection type. Let's 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) , this does not initiate a query to the associated data to load the associated data, only the (2) , the real data-reading operation will begin when Hibernate finds entity objects that match the criteria based on the data index that matches the criteria in the cache. here we introduce a whole new concept--data index, and we'll take a look at what the data index is first. In the Hibernate is cached in two parts when the collection type is cached, first caching all entities in the collection . ID list, and then caching the entity objects, which ID list, which is called the data index. When looking for a data index, if the corresponding data index is not found, a Select SQL , get the data that meets the criteria, construct the collection of entity objects and data indexes, and then return the collection of entity objects and include the entity objects and data Indexes Hibernate Cache. If, on the other hand, the corresponding data index is found, it is removed from the data index ID list, and then according to the ID find the corresponding entity in the cache, and if found, return from the cache, if not found, in the initiating Select SQL query. Here we see another problem that may have an impact on performance, which is the caching strategy for the collection type. If we 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> here we have applied <cache usage= "read-only"/> configuration, if this policy is used to configure the collection type, Hibernate The data index is cached only, not the entity objects in the collection. As configured above we run the following code: 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 get 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 we see that when the query executes the second time, two pairs of Address Table Query operation, why is this. This is because when an entity is loaded for the first time, the collection data index is cached based on the configuration of the collection type caching policy, and the entity objects in the collection are not cached, so the second time the entity is loaded again, Hibernate The data index for the corresponding entity was found, but the corresponding entity could not be found in the cache based on the data index, so Hibernate Two articles were launched based on the data index found Select SQL query operation, which has caused a waste of performance, how to avoid this situation. We must also specify a caching policy for the entities in the collection type, so we have to 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-write"/> <key column= "user_id"/> <one-to-many class= "Com.neusoft.entity.Arrderss"/> </set> </class> at this point Hibernate The entities in the collection type are also cached, and if you run the above code again based on this configuration, 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 queries based on the data index. SQL statement, because the entity objects stored in the collection type can be obtained directly from the cache at this time. C, Property Deferred loading:    in the Hibernate3 , a new feature-deferred loading of attributes-is introduced, which provides a powerful tool for obtaining high-performance queries. Before we talk about the large data object reading, the User the object has a Resume field, which is a Java.sql.Clob type, which contains the user's resume information, and when we load the object, we have to load the field every time, regardless of whether we really need it, and the reading of such a large data object can have a significant performance overhead. In the Hibernate2 , we can only decompose the particle size of the surface performance we talked about earlier. User class to solve the problem (refer to the section), but Hibernate3 , we can get the ability to read the field data only when we really need to manipulate the field, so we have to configure our entity classes as follows: <class name= "Com.neusoft.entity.User" table= "User" > ..... <property name= "Resume" type= " Java.sql.Clob" column= "Resume" lazy= "true"/> </class> through the <property> Elements of Lazy Property Settings true to turn on deferred loading of the property, Hibernate3 class intensifier is used to implement the deferred loading of the attribute for the entity class Class The enhanced processing of the file, through the enhancement of the amplifier, will Cglib callback mechanism logic, add the entity class, where we can see the delay loading of the property, or the Cglib to achieve. Cglib is Apache an open source project, this class library can manipulate Java The byte code of the class that dynamically constructs the class object that conforms to the requirement based on the byte code. Based on the configuration above, we run the following code: String sql= "from 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 executing to (1) , you will generate a similar SQL statement: Select id,age,name from user where name= ' ZX '; then Hibernate will retrieve User the field data for all non-deferred load properties in the entity, when executed to the (2) , you will generate a similar SQL statement: Select resume from user where id= ' 1 '; This will initiate the Resume the actual read operation of the field data.

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.