How hibernate delays Loading

Source: Internet
Author: User
Delayed loading:

The delayed loading mechanism is proposed to avoid unnecessary performance overhead. The so-called delayed loading means that data loading is performed only when data is actually needed. Hibernate provides delayed loading of object objects and delayed loading of collections, and delayed loading of attributes in hibernate3. Next we will introduce the details of these types of delayed loading.

A. Delayed loading of object:

To use delayed loading for object objects, you must configure the object ing configuration file as follows:

<Hibernate-mapping>

<Class name = "com. Neusoft. entity. User" table = "user" lazy = "true">

......

</Class>

</Hibernate-mapping>

You can enable the delayed loading feature of an object by setting the lazy attribute of the class 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 at (1), Hibernate does not initiate data query. If we use some debugging tools (such as jbuilder2005's debug tool ), observe the memory snapshot of the user object. We are surprised to find that the returned user $ enhancerbycglib $ bede8986 type object and its attribute is null. What is the problem? I still remember that the session. Load () method previously mentioned will return the proxy class Object of the object. Here, the returned object type is the proxy class Object of the user object. In hibernate, cglib is used to dynamically construct the proxy class object of a target object, and the proxy class object contains all the attributes and methods of the target object, all attributes are assigned null values. Whether the values get attribute is null. If it is not null, The getname method of the target object is called. If it is null, a database query is initiated to generate an SQL statement similar to this: select
* From user where id+'1'then to query data, construct the target object, and assign the value to the cglib?calback_0.tar get attribute.

In this way, through an intermediate proxy object, Hibernate achieves object loading delay. Only when a user initiates an action to obtain object attributes can the user initiate a database query operation. Therefore, the delayed loading of objects is completed through the intermediate proxy class, so only session is available. the load () method uses the object to delay loading, because only the session. the load () method returns the proxy class Object of the object class.

B. Delayed loading of Collection types:

In the delayed Loading Mechanism of hibernate, it is of the most significant significance for the application of the set type, because it may greatly improve the performance, so hibernate has made a lot of efforts, this includes the independent implementation of JDK collection. In one-to-Multiple Association, the Set set defined to hold the associated object is not Java. util. set type or its subtype, but net. SF. hibernate. collection. set type. hibernate implements delayed loading of set types by using custom collection classes. To use delayed loading for the collection type, we must configure the related section of our object class as follows:

<Hibernate-mapping>

<Class name = "com. Neusoft. entity. User" table = "user">

.....

<Set name = "addresses" table = "address" lazy = "true" inverse = "true">

<Key column = "user_id"/>

<OnE-to-convert class = "com. Neusoft. entity. arrderss"/>

</Set>

</Class>

</Hibernate-mapping>

Set the lazy attribute of the <set> element to true to enable the delayed loading feature of the set 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) it. Next ();

System. Out. println (address. getaddress ());

}

When the program is executed at (1), no query is initiated for the associated data to load the associated data. Only when the program runs at (2, the real data read operation starts. At this time, Hibernate searches for object objects that meet the condition based on the Qualified Data Index in the cache.

Here we introduce a new concept-Data Index. Next we will first take a look at what is data index. In hibernate, the set type is cached in two parts. First, the IDs of all objects in the set are cached, and then the object IDs are cached, it is the so-called data index. When you look for a data index, if the corresponding data index is not found, a select SQL statement is executed to obtain Qualified Data and construct a collection of Entity objects and data indexes, then return the collection of object objects and include the object objects and data indexes in the cache of hibernate. On the other hand, if the corresponding data index is found, the ID list is retrieved from the data index, and the corresponding entity is searched in the cache based on the ID. If it is found, it is returned from the cache, if not, select
SQL query. Here we can see another problem, which may affect the performance. This is a cache policy of the collection type. If we configure the collection type as follows:

<Hibernate-mapping>

<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-convert class = "com. Neusoft. entity. arrderss"/>

</Set>

</Class>

</Hibernate-mapping>

Here we have applied <Cache Usage = "read-onLy "/> Configuration. if this policy is used to configure the collection type, Hibernate will only cache the data index, rather than the Entity objects in the set. Run the following code for the above Configuration:

User user = (User) Session. Load (user. Class, "1 ");

Collection addset = user. getaddresses ();

Iterator it = addset. iterator ();

While (it. hasnext ()){

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 ());

}

Run this code to 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 can see that when the second query was executed, two queries were performed on the address table. Why? This is because after loading an object for the first time, according to the configuration of the cache policy of the collection type, only the collection data index is cached, and the object objects in the collection are not cached, therefore, when the object is loaded again for the second time, Hibernate finds the data index of the corresponding object, but it cannot find the corresponding object in the cache according to the data index, therefore, Hibernate initiates two select SQL queries based on the data index. This results in a waste of performance. How can we avoid this situation? We must specify a cache policy for the objects in the collection type. Therefore, we need to configure the collection type as follows:

<Hibernate-mapping>

<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-convert class = "com. Neusoft. entity. arrderss"/>

</Set>

</Class>

</Hibernate-mapping>

At this time, Hibernate will cache the objects in the set type. If you run the above Code again based on this configuration, the following output will be obtained:

Select * from user where id = '1 ';

Select * From address where user_id = '1 ';

Tianjin

Dalian

Second query ......

Tianjin

Dalian

In this case, no SQL statement is used to query data indexes, because the Entity objects stored in the set type can be directly obtained from the cache.

C. Delayed attribute loading:

In hibernate3, a new feature-delayed loading of attributes is introduced, which provides a powerful tool for obtaining high-performance queries. As mentioned above, when reading a big data object, there is a resume field in the user object, which is a Java. SQL. the clob type contains the user's resume information. When we load this object, we have to load this field every time, whether or not we really need it, in addition, reading such big data objects will bring about great performance overhead. In hibernate2, we only break down the user class through the granularity subdivision of the surface performance we mentioned earlier (refer to the discussion in that section ), however, in hibernate3, we can use the property delay loading mechanism to obtain the ability to read data from this field only when we really need to operate on this field, therefore, we must configure our object class as follows:

<Hibernate-mapping>

<Class name = "com. Neusoft. entity. User" table = "user">

......

<Property name = "resume" type = "Java. SQL. clob" column = "resume" lazy = "true"/>

</Class>

</Hibernate-mapping>

You can set true for the lazy attribute of the <property> element to enable delayed loading of the attribute. In hibernate3, to achieve delayed loading of the attribute, the class enhancement tool is used to enhance the class file of the object class. Through the Enhancement Tool, the logic of the callback mechanism of cglib is added to the object class. Here we can see the delayed loading of the attribute, it is implemented through cglib. Cglib is an open-source project of Apache. This class library can manipulate the bytecode of Java classes and dynamically construct class objects that meet the requirements according to the bytecode. Based on the preceding configuration, 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 executed at (1), an SQL statement similar to the following will be generated:

Select ID, age, name from user where name = 'zx ';

At this time, Hibernate will retrieve all the field data corresponding to the non-delayed loading attribute in the user object. When it is executed at (2), it will generate an SQL statement similar to the following:

Select resume from user where id = '1 ';

In this case, a real read operation is initiated on the resume 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.