Hibernate Reading Notes ----- lazy loading analysis

Source: Internet
Author: User

Lazy loading means that the program delays accessing the database. This ensures that sometimes it is unnecessary to access the database because it is time-consuming to access the database once.
I. load Method lazy loading
First look at the following code segment
[Java]
<Span style = "font-size: 16px;"> public class UserManager {
 
Public static void main (String [] args ){
Users user = new Users ();
User. setBirthday (new Date ());

Name name = new Name ();
Name. setFirstName ("guo ");
Name. setLastName ("zhao ");

User. setName (name );
AddUser (user );

Users users = getUser (user. getId ());
System. out. println (users. getName ());

}


Static Users getUser (int id ){
Session session = HibernateUtil. getSession ();
Try {
Users users = (Users) session. load (Users. class, id );
Return users;
} Finally {
Session. close ();
}
}

Static void addUser (Users users ){
Session session = null;
Transaction tx = null;

Try {
Session = HibernateUtil. getSession ();
Tx = session. beginTransaction ();
 
Session. save (users );
Tx. commit ();
} Catch (HibernateException e ){
If (tx! = Null ){
Tx. rollback ();
}
Throw e;
} Finally {
If (session! = Null ){
Session. close ();
}
}
}
} </Span>

The code above adds a user first, and then queries the name combination attribute of the user. When running the above Code, the program throws such an exception:
Exception in thread "main" org. hibernate. LazyInitializationException: cocould not initialize proxy-no Session. This means that the initialization error cannot be caused by lazy loading. The reason is that no session. As described in the previous Persistent object, when the load method is used, this method will have the function of delayed loading. The load method does not access the database immediately and will return a proxy object, only when you actually access this object will it access the database.
From the figure above, we can see that hibernate does not have a select statement at all, that is to say, hibernate does not access the database, so there is definitely no access to it at this time. But why didn't I throw a null pointer exception? No NULL pointer exception is thrown. That is to say, the User object exists. What is it? The output user. getClass () shows the following:
Class com. hibernate. domain. Users _ $ _ export sist_5.
This user is the proxy object returned by load. But this object is not what we want. What we want is a User instance object.
So how can we solve this problem?
Method 1: access the object before closing the session
[Java]
<Span style = "font-size: 16px;"> static Users getUser (int id ){
Session session = HibernateUtil. getSession ();
Try {
Users users = (Users) session. load (Users. class, id );
Users. getName ();
Return users;
} Finally {
Session. close ();
}
} </Span>
However, this sentence may seem strange. We usually use the following method:
[Java]
<Span style = "font-size: 16px;"> static Users getUser (int id ){
Session session = HibernateUtil. getSession ();
Try {
Users users = (Users) session. load (Users. class, id );
Hibernate. initialize (users );
Return users;
} Finally {
Session. close ();
}
} </Span>
Use the initialize () method of hibernate to initialize this proxy object.
Note: When the getId () method and getClass () method of the proxy object are used, the initialization exception is not thrown because these two attributes are not used to query the database.
 
Ii. By default, hibernate uses the lazy loading method for associations. That is to say 1-1, 1-N, N-1, N-N have the problem of lazy loading.
2.1 one-to-one lazy loading
One-to-one lazy loading is not commonly used, because lazy loading aims to reduce interaction with databases and improve execution efficiency. In a one-to-one relationship, each piece of data in the primary table corresponds to only one database from the table. Even if you query the data, it will not increase the interaction cost, and the primary table cannot have contrained = true, therefore, the primary table cannot be loaded lazily. But the slave table can.
To implement this type of lazy loading, three conditions must be met simultaneously from the object side:
1. lazy! = False (lazy attributes have three options: no-proxy, false, and proxy)
2. Constrained = true;
3. fetch = select.
Note: When fetch is set to join, lazy loading will fail. Because fetch is used to capture data, it has two values: select and join. The default value is select. That is, when it is set to join, it will directly query the table information in join mode instead of using select query again, which leads to lazy loading failure.
 
2.2 one-to-one lazy loading
Different from the one-to-one association, for one-to-one association, each attribute of the master table corresponds to multiple data records from the table, in this case, lazy loading is very effective. For example, if a department has multiple employees and is not loaded lazily, multiple employees will be queried every time this department is queried, which will greatly increase the cost of interacting with the database. Therefore, Hbernate is added with lazy loading by default. This is why a PersistentIndexed * type object is returned when querying the set attributes. This object is actually a proxy object. Of course, you can disable the lazy attribute in the ing file by setting it to false.
By default, Hibernate uses the one-to-one method for lazy loading, but you can also cancel the lazy loading operation:
1. Set lazy = "false ";
2. Set fetch = "join ".
To implement this type of lazy loading, you must meet two conditions at the same time from the object side:
1. lazy! = False (lazy attributes have three options: no-proxy, false, and proxy)
2. fetch = select.
 
2.3 mang-to-one lazy loading
The lazy loading of this association is the same as the lazy loading of one-to-one, because the improvement in execution efficiency is not very obvious. Although many-to-one and one-to-one are in the same way, when many-to-one is in Hibernate, the load is lazy by default. In addition, it should be noted that lazy loading does not distinguish whether there is a value in the set attribute. Even if there is no value, it will still use lazy loading.
To implement this type of lazy loading, you must meet two conditions at the same time from the object side:
1. lazy! = False (lazy attributes have three options: no-proxy, false, and proxy)
2. fetch = select
 
2.4. Allow-to-Allow lazy loading
The lazy loading of this association is the same as the lazy loading of one-to-one relationship, which improves the execution efficiency of the program.
To implement this type of lazy loading, you must meet two conditions at the same time from the object side:
1. lazy! = False (lazy attributes have three options: no-proxy, false, and proxy)
2. fetch = select
Objects that can be loaded lazily are modified proxy objects. When the corresponding objects are not closed, hibernate will initialize these proxies to access the properties of these lazy objects (except getId and getClass, or use hibernate. initalize (proxy) is used to initialize the proxy object. When the session is closed, an exception will occur when the access to the objects to be loaded is lazy.


Author: chenssy

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.