Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the delay loading of Hibernate and lazy Mechanism

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces the knowledge of "Hibernate delayed loading and how to solve the lazy mechanism". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

Hibernate delay loading, in fact, this exception is written very clearly, that is, the session is closed and cannot operate on the Hibernate entity. There are many such situations, such as writing mistakes and logic errors.

But here's a little bit about the lazy mechanism:

Hibernate deferred loading includes deferred initialization errors, which are the most common errors when working with Hibernate development projects. If a deferred retrieval policy is configured on a class or collection, it can only be initialized when the proxy class instance or collection is in a persistent state (that is, within the scope of Session). If it is initialized in a free state, a delayed initialization error occurs.

The following is the Customer.hbm.xml file

< class>

The lazy attribute of the element is set to true, which means that a deferred retrieval strategy is used:

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

When the load () method of Session is executed, Hibernate does not immediately execute the select statement that queries the CUSTOMERS table, but only returns an instance of the proxy class of the Customer class, which has the following characteristics:

(1) generated dynamically by Hibernate at run time, it extends the Customer class, so it inherits all the properties and methods of the Customer class, but its implementation is transparent to the application.

(2) when Hibernate creates an instance of the Customer proxy class, only its OID property is initialized, and all other properties are null, so this proxy class instance takes up very little memory.

(3) when the application accesses the Customer proxy class instance * * times (such as calling the customer.getXXX () or customer.setXXX () method), Hibernate initializes the proxy class instance, executes the select statement during the initialization process, and actually loads all the data of the Customer object from the database. With one exception, when the application accesses the getId () method of the Customer proxy class instance, Hibernate does not initialize the proxy class instance, because OID exists when the proxy class instance is created and does not have to be queried in the database.

Tip: Hibernate uses the CGLIB tool to generate proxy classes for persistent classes. CGLIB is a powerful Java bytecode generation tool, which can dynamically generate proxy classes that extend Java classes or implement Java interfaces when the program is running.

The following code first loads the Customer object through the load () method of Session, and then accesses its name property:

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

Hibernate does not execute any select statements when the session.load () method is run, but simply returns an instance of the proxy class of the Customer class, whose OID is 1, which is specified by the second parameter of the load () method. When the application calls the customer.getName () method, Hibernate initializes the Customer proxy class instance, loads the data of the Customer object from the database, and executes the following select statement:

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

When

< class>

The lazy attribute of the element is true, which affects the various runtime behaviors of the load () method of Session, which is illustrated below.

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

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

2. If the application has not accessed the Customer object throughout the Session scope, the instance of the Customer proxy class will never be initialized and Hibernate will not execute any select statements. The following code attempts to access the Customer free object after closing Session:

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

Because an instance of the Customer proxy class referenced by the reference variable customer is never initialized within the scope of Session, Hibernate throws the following exception when executing the customer.getName () method (one of the problems with Hibernate deferred loading):

ERROR LazyInitializer:63-Exception initializing proxy net.sf.hibernate.HibernateException: Couldnotinitializeproxy-theowningSessionwasclosed

Thus, an instance of the Customer proxy class can only be initialized within the current Session scope.

The initialize () static method of the 3.net.sf.hibernate.Hibernate class is used to explicitly initialize the proxy class instance within the scope of the Session, and the isInitialized () method is used to determine whether the proxy class instance has been 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 explicitly initializes the instance of the Customer proxy class through the initialize () method of the Hibernate class within the scope of Session, so that when Session is closed, the Customer free object can be accessed normally.

4. When an application accesses the getId () method of an instance of a proxy class, the behavior of Hibernate initializing the instance of the proxy class is not triggered, for example:

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

When the application accesses the customer.getId () method, the method directly returns the OID value of the instance of the Customer proxy class without querying the database. Because the reference variable customer always refers to an instance of the Customer proxy class that has not been initialized, when Session is closed and then executes the customer.getName () method, Hibernate throws the following exception (one of the problems with Hibernate delayed loading):

ERROR LazyInitializer:63-Exception initializing proxy net.sf.hibernate.HibernateException: Couldnotinitializeproxy-theowningSessionwasclosed

Solution:

Because hibernate uses lazy=true, when you query with hibernate, it returns the proxy class that is actually enhanced by cglib, but it is not actually filled; when you are in the front end, using it to take value (getXXX), then Hibernate will go to the database to execute the query and populate the object, but at this time, if the session associated with this proxy class has been closed, an error will occur.

When doing a pair of long, sometimes there will be "could not initialize proxy-clothe owning Session was sed, which seems to be the cache problem of hibernate." problem solving: need to be in the

< many-to-one>

Set lazy= "false" in. But it is possible to throw another exception called

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

Solution: add to web.xml

< filter>

< filter-name>

HibernateFilter

< /filter-name>

< filter-class>

Org.springframework.orm.hibernate3.support.OpenSessionInViewFilter

< /filter-class>

< /filter>

< filter-mapping>

< filter-name>

HibernateFilter

< /filter-name>

< url-pattern>

* .do

< /url-pattern>

< /filter-mapping>

Just do it.

This is the end of the content of "Hibernate delayed loading and how to solve the lazy mechanism". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report