Hibernate's lazy-loading mechanism (lazy mechanism)

Transfer from http://blog.sina.com.cn/s/blog_5719dd050100b66f.html

HIBERNATE the persistent object loading strategy.
Delay load, that is, when it is used to load. This can increase the number of properties.
Hibernate's lazy loading a HibernateSession used to manage the session, its logic is once every database operation, on opening the new session, immediately after the operation to close the session. This advantage is strictly closed session, to avoid the rookie-level error, but hibernate.org is not recommended. Because it is not suitable for lazy loading, are not suitable for cross-method affairs.
For example, in our applications, user-> post the formation of one to many mapping, User has a post that contains the List.
In the User, there are several attributes: name, password, phone, etc., and a List type of posts. When we use the lazy laoding posts when, hibernate will be when the User object, only to return name, password, phone and other basic properties, the time when you visit the posts, it will extract the posts from the database necessary data, the so-called lazy laoding. But in our system, session are immediately closed, that is, read the name, password, phone, etc. After the basic attributes, session has been close, and then there will be exceptions for lazy loading.
The solution is to close session before, calling Hibernate.initialize (user.getPosts ()), tell the system, user.getPosts () is the need lazy laoding's. But doing so would undermine HibernateSession class package.
Later, using the so-called OpenSessionInView mode, the session of the cycle to the servlet filter to manage, every time a request came in, it opens a session, response and then close it after, so that session can exist in the request cycle.

Hibernate lazy in Lazy
Hibernate the one-to-one and many-to-one in the query's father side lazy problem
Hibernate3 lazy in the association have this property, if Hibernate2, should be set outer-join = "false", then the associated object, that place in the class setting lazy = "true". First of all, for many-to-one in problem, you can end the class labels in his father set lazy to solve, so that the query son, does not send extra sql.
For one-to-one, in hibernate2 which, as one-to-one option which is not lazy, so only by setting outer-join = "false" to solve. The hibernate3 has joined the lazy, so it will not have this problem.
Overall, if you find that you check the time his son has extra sql to send, it must be a misuse of your hibernate ..

In hibernate in one-to-many, many-to-one, many-to-many, in order to improve efficiency, we generally use lazy mechanism, but use the spring of getHibernateTemplate (). Save (Object) when, HibernateTemplate attempt execute each time to get before the Session, the implementation of End to strive to close the Session. That is Hibernate's Lazy initialization 1: n relationship, you must ensure that in the same Session set for internal use this relationship, or Hiernate throws Failed to lazily initialize a collection - no session or session was closed exception.

Hibernate objects in the association (association) of the set is not enough flexible and practical application in some places need to lazy load, in some places they do not, in fact, where there is no need to use association. In Hibernate, mapping files can only be set in a way, applications like ours, I am afraid to use the open session in view of (slower is better than living lock), can only either do not set association or is lazy = true to. Classification of information previously only used a many to one relationship, the price can be put up, but now more and more complicated relationship, and then add a few words, to pay performance, bandwidth, the price probably will not be ignored, Even with a little cache to improve performance, the waste of bandwidth is also unforgivable.

Hibernate lazy initialization error is the use of development projects in the most common mistakes. If a class or a set of configuration of the delay in search strategy, you must when the proxy class instance or a collection agency in the persistent state (that is in Session range) time to initialize it. If the free state when the initialization it will have delay initialization error.

The following documents to Customer.hbm.xml <class> element lazy attribute set to true, that the use of delayed retrieval strategy:

<class name="mypack.Customer" table="CUSTOMERS" lazy="true">

When the Executive Session of the load () method, Hibernate will not execute the query immediately CUSTOMERS table select statement, only the Customer class to return an instance of the proxy class, the proxy class with the following characteristics:

(1) from Hibernate dynamically generated at run time, it extends the Customer class Customer class so it inherits all the properties and methods, but its implementation is transparent to applications.
(2) When Hibernate creates a proxy class instance of Customer, just initialize its OID attributes, and other properties are null, so this proxy class instance take up very little memory.
(3) When the application first visit to the Customer Agent class instances (for example, call customer.getXXX () or customer.setXXX () method), Hibernate will initialize the proxy class instance, in the initialization process of implementation of the select statement, the real from the database load Customer object all the data. However, an exception, that is when the application to access Customer proxy class instance getId () method, Hibernate does not initialize the proxy class instance, because in creating the proxy class instance of OID on the existence, not to the database to query .

Tip: Hibernate uses CGLIB tool to generate the persistent classes of the proxy class. CGLIB is a powerful Java byte code generation tool, it can run dynamically generated extend Java classes or implement Java interfaces of the proxy class. About CGLIB-more knowledge, please refer to: http://cglib.sourceforge.net/.

The following code to pass Session of the load () method to load the Customer object, then access it in the name attribute:

tx = session.beginTransaction ();
Customer customer = (Customer) session.load (Customer.class, new Long (1));
customer.getName ();
tx.commit ();

Running session.load () method, Hibernate does not execute any select statement, only to return Customer class, proxy class instance, its OID is 1, which is the load () method of the second parameter specified. When an application calls customer.getName () method, Hibernate will initialize the Customer agent class instance, from the database load Customer object data, perform the following select statement:

select * from CUSTOMERS where
select * from ORDERS where CUSTOMER_ID = 1;

When <class> element lazy attribute to true, will affect the Session of the load () method of the various run-time behavior, the following example.

1. If the load of the Customer object in the database does not exist, Session of the load () method does not throw an exception, only when running customer.getName () method will throw the following exception:

ERROR LazyInitializer: 63-Exception initializing proxy
net.sf.hibernate.ObjectNotFoundException: No row with thegiven identifier exists: 1, of class:
mypack.Customer

2. If the Session context, the application has not visited the Customer object, then the Customer agent instance of the class has not been initialized, Hibernate will not execute any select statement. The following code is trying to close the Session to visit Customer free object:

tx = session.beginTransaction ();
Customer customer = (Customer) session.load (Customer.class, new Long (1));
tx.commit ();
session.close ();
customer.getName ();

As the reference variable customer references Customer proxy instance of the class in Session range has not been initialized, and therefore customer.getName () method, Hibernate will throw the following exception:

ERROR LazyInitializer: 63-Exception initializing proxy
net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed

Thus, Customer proxy instance of the class only in the current Session context to be initialized.

3. net.sf.hibernate.Hibernate class initialize () static method is used in the Session context explicitly initialize the proxy class instance, isInitialized () method is used to determine the proxy class instance is already initialized. For example:

tx = session.beginTransaction ();
Customer customer = (Customer) session.load (Customer.class, new Long (1));
if (! Hibernate.isInitialized (customer))
Hibernate.initialize (customer);
tx.commit ();
session.close ();
customer.getName ();

The above code in the Session context through Hibernate class initialize () method explicitly initialize the Customer agent class instance, so when the Session closed, you can normally visit the Customer free object.

4. When an application to access the proxy class instance getId () method will not trigger Hibernate initialize proxy class instances, such as:

tx = session.beginTransaction ();
Customer customer = (Customer) session.load (Customer.class, new Long (1));
customer.getId ();
tx.commit ();
session.close ();
customer.getName ();

When an application to access customer.getId () method, the method directly returns Customer proxy class instance of OID values, without querying the database. As the reference variable customer is always cited is not initialized Customer proxy class instance, so when the Session closed after the implementation of the customer.getName () method, Hibernate throws the following exception:

ERROR LazyInitializer: 63-Exception initializing proxy
net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed

Solution:

Because hibernate using lazy = true, so that when you use hibernate query, returns the actual for the use of cglib enhanced proxy class, but not actually filled; when you front-end, using it to value (getXXX), the time Hibernate only to the database execute the query, and populate the object, but at this time if and the proxy class associated session has been closed off, it will produce kinds of errors.
Doing one to many, sometimes appears "could not initialize proxy - clothe owning Session was sed, this seems to hibernate cache issue. Problem-solving: the need <many-to-one> in setting lazy =" false ". But may trigger another exception called

failed to lazily initialize a collection of role: XXXXXXXX, no session or session was closed

Solution: In the web.xml adding OpenSessionInViewFilter
  • del.icio.us
  • StumbleUpon
  • Digg
  • TwitThis
  • Mixx
  • Technorati
  • Facebook
  • NewsVine
  • Reddit
  • Google
  • LinkedIn
  • YahooMyWeb

Related Posts of Hibernate's lazy-loading mechanism (lazy mechanism)

  • hibernate study of the second

    Persistence of three main points: 1, a statement for persistent fields accessors (accessors) and whether the variable signs (mutators) Property statement is not necessarily required for the public's. Hibernate can be default, protected or private ...

  • JS after ajax request return of the problem can not be implemented

    1: Send ajax request, in the onComplete, if back when the html contains a javascript, then these javascrip and will not be realized, it does not mean not to implement. This problem has troubled me for a long time, behind the hair and then put this kn ...

  • hibernate load delay

    Lazy loading: Lazy loading mechanism is in order to avoid unnecessary performance overhead and put forward the so-called lazy loading is required when the real data at a time when the real implementation of the data load operation. At Hibernate provides f

  • Hibernate in the inverse and cascade

    First of all, to quote another blog saying: 1.cascade ="..."? cascade is not a property of many-to-many relationship must have it just so that we insert or delete at the time like some more convenient, as long as the source of the cascade insert

  • To a generic hibernate example DAO

    Reprint: http://blog.csdn.net/dingx package sgf4web.dao; import java.io.Serializable; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.hibernate.*; import org.hibernate.criterion.*; import org.springframework.

  • Hibernate Inteceptor

    The end of the project stage, the client suddenly put forward a very troublesome but normal demand, the system records all changes must be carried out. Formats such as: 2004.1.1 12:30 Ikuya wind orders Sales Order Date 2004.1.2-> 2004.1.3 The firs ...

  • EJB

    public transient int counter; / / transient property private String firstname; / / persistent property @ Transient String getLengthInMeter () (...) / / transient property String getName () (...) / / persistent property @ Basic int getLength () (...) / / p

  • JDBC example of a long time do not have JDBC forgot

    A back-up here to stay. The first: The second:

  • JAVA Class naming convention

    1. Entity Layer: Inheritance: All categories inherited from BasicEntity, one of BasicEntity implementation java.io.Serializable interface; Naming rules: Class Name = Object + type suffix, one of type suffix for Bean, such as: SalesOrderBean 2. Form l ...

  • Application of spring struts2.0 hibernate HQL

    Therefore, in the development of statistical inquiry system, as far as possible through the use of select statement to write the required query property way back relational data, and avoid using the first query return persistent object (in this way are in

blog comments powered by Disqus
Recent
Recent Entries
Tag Cloud
Random Entries