Hibernate lazy Loading and immediate loading

Source: Internet
Author: User

Concept

What is lazy loading: the so-called lazy load is when the data is really needed to actually perform the data load operation. It can be simply understood that only when used, the SQL statement is issued to query, the data is divided into N-times read.

What is immediately loaded: the so-called immediate load is both all relevant data being read out at once, instead of being divided n times.

one, delayed loading: NHibernate delayed loading must have Session exists, and is configured as lazy=true (default)

The DAL is written in the following ways:

Lazy Loading

Public Order Lazyload ()

{

ISession will continue to exist after returning the order object

return session. Get<order> (2);

ISession will be destroyed immediately after the order is returned.

using (ISession ISession = new SessionManager (). GetSession ())

//{

Order order = isession.get<order> (2);

return order;

//}

}

There are two ways to return the order object, one to return to order after the session continues to exist, one after the return order after the session is destroyed, we first use the non-annotated method, and then use the annotated code.

DAL. Test, write the following method:

[Test]

public void Lazyloadtest ()

{

Order order = Sample. Lazyload ();

}

Then set breakpoints, perform test debugging, and write code tests in the Immediate window.

When the session continues to exist after returning to order, the result is as follows:

Order. Orderdate.tostring ()

"2009-10-17 11:22:46"

Order. Customer.firstname

"Soldier"

Order. Products.count

2

As you can see here, we can access the associated object of the Order object customer and products

When the session is destroyed immediately after returning to order, the result is as follows:

Order. Orderdate.tostring ()

"2009-10-17 11:22:46"

Order. Customer.firstname

"Order. Customer.firstname "Nhibernate.lazyinitializationexception" type exception was thrown

Base {nhibernate.hibernateexception}: {"Initializing[model.entities.customer#2]-could not initialize Proxy-no Session. "}

Entityid:2

EntityName: "Model.Entities.Customer"

Order. Products.count

"Order. Products.count "Nhibernate.lazyinitializationexception" type exception was thrown

Base {nhibernate.hibernateexception}: {"initializing[model.entities.order#2]-failed to lazily initialize a collection of Role:Model.Entities.Order.Products, no session or session was closed "}

Entityid:2

EntityName: "Model.Entities.Order"

Here we can access the order object, which is for granted. However, whenever I access the order's associated object, customer or products, the "nhibernate.lazyinitializationexception" exception is reported because the access is using lazy loading, However, the session has been destroyed at this time, so the error, which indicates that the use of lazy loading must ensure that the session is present.

second, immediately load: There are three ways to load immediately, one, configuration lazy= "false" ; second, use Nhibernateutil third, use the band Fetch of the HQL Statement

1) Configure lazy= "false" for immediate loading

First modify the Order.hbm.xml file to

<bag name= "Products" generic= "true" table= "Orderproduct" >

The changes are as follows:

<bag name= "Products" generic= "true" table= "Orderproduct" lazy= "false" >

And then test again, the results are as follows:

Order. Orderdate.tostring ()

"2009-10-17 11:22:46"

Order. Products.count

2

Order. Customer.firstname

"Order. Customer.firstname "Nhibernate.lazyinitializationexception" type exception was thrown

Base {nhibernate.hibernateexception}: {"Initializing[model.entities.customer#2]-could not initialize Proxy-no Session. "}

Entityid:2

EntityName: "Model.Entities.Customer"

You can see that products configured with lazy= "false" can be accessed because its data has been read with order, but when we visit the customer, we report the errors we have seen above, Because the customer is not configured for immediate loading in the order mapping file, an error is given.

2) Force immediate loading using the Nhibernateutil class

The code to first modify the Lazyload () function is as follows:

ISession will be destroyed immediately after the order is returned.

using (ISession ISession = new SessionManager (). GetSession ())

{

Order order = isession.get<order> (2);

Nhibernateutil.initialize (order.                   Customer); This forces the associated customer object to immediately load the order

return order;

}

The test results are as follows:

Order. Orderdate.tostring ()

"2009-10-17 11:22:46"

Order. Products.count

2

Order. Customer.firstname

"Soldier"

Haha, you can also access the Customer object.

3) using HQL query with fetch

A) using the HQL Query method can also be loaded immediately. The HQL statement supports the following types of connections: INNER JOIN (inner join), left OUTER join (off outer join), right outer join (off-side connection), full join (fully connected, not common).

b) The fetch FETCH connection allows the associated object to be initialized with the initialization of their parent object using only a single selection statement, which effectively replaces the outer join and deferred attribute declarations in the mapping file.

Some notes:

c) Fetch is not shared with setmaxresults () or Setfirstresult () because these operations are based on the result set, and may contain duplicate data when the collection is pre-fetched, meaning that the exact number of rows cannot be known beforehand.

d) fetch cannot be used with separate with conditions. By fetch multiple sets in a single query, you can create a Cartesian product, so please pay more attention. For many-to-many mappings, also be careful that join fetch multiple collection roles may give unexpected results in some cases.

e) There is no point in using full join fetch with RIGHT join FETCH. If you use attribute-level deferred fetching, you can use the fetch all property in the first query to force NHibernate to immediately get those properties that would otherwise require lazy loading.

Remove the lazy= "false" property setting in Order.hbm.xml so that the order products are not immediately loaded, and the Lazyload () function is modified as follows:

Lazy Loading

Public Order Lazyload ()

{

ISession will continue to exist after returning the order object

return session. Get<order> (2);

ISession will be destroyed immediately after the order is returned.

using (ISession ISession = new SessionManager (). GetSession ())

//{

Order order = isession.get<order> (2);

Nhibernateutil.initialize (order. Customer);

return order;

//}

Use HQL fetch for immediate loading

using (ISession ISession = new SessionManager (). GetSession ())

{

Return Isession.createquery ("from Order O left join fetch o.products where o.orderid=2")

. Uniqueresult<order> ();

}

}

The debug test results are as follows:

Order. Orderdate.tostring ()

"2009-10-17 11:22:46"

Order. Products.count

2

Order. Customer.firstname

"Order. Customer.firstname "Nhibernate.lazyinitializationexception" type exception was thrown

Base {nhibernate.hibernateexception}: {"Initializing[model.entities.customer#2]-could not initialize Proxy-no Session. "}

Entityid:2

EntityName: "Model.Entities.Customer"

In the HQL statement above, the products are loaded immediately with the FETCH o.products statement, so the products can be accessed in the test, and when the customer is visited, an error occurs.

Then we modify the HQL statement above:

"From Order O left join fetch o.products where o.orderid=2"

as follows

"From Order O LEFT join fetch o.products INNER JOIN fetch o.customer where o.orderid=2"

And then the same test as above to see how the results, my following:

Order. Orderdate.tostring ()

"2009-10-17 11:22:46"

Order. Products.count

2

Order. Customer.firstname

"Soldier"

Hibernate lazy Loading and immediate 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.