Current location - Loan Platform Complete Network - Big data management - hibernate, what is the state of the object loaded from session, is it persistent?
hibernate, what is the state of the object loaded from session, is it persistent?
Persistent state: The object establishes a correspondence with the database record and keeps it synchronized. The object is bound in the persistence context, any future state changes, data changes are under the management of the unit of work, this is the persistent state. session.load in hibernate3.2 provides the default delayed loading method, I think load out of a proxy, can also be said to be persistent state (their own understanding of this, such as a mistake please a master to correct). ).

To understand the delayed loading, it helps to understand the delayed loading:

The delayed loading mechanism is to avoid some unnecessary performance overhead and put forward, the so-called delayed loading is when in the real need for the data, only to really perform the data loading operation. In Hibernate provides delayed loading of entity objects and delayed loading of collections, in addition to Hibernate3 provides delayed loading of properties. Below we describe the details of each of these kinds of delayed loading.

A. Delayed loading of entity objects:

If you want to use delayed loading of entity objects, you must configure the entity mapping configuration file accordingly, as follows:

<hibernate-mapping>

<class name= "com.neusoft.entity.User" table="user" lazy="true">

......

</class>

</hibernate-mapping>

Enable the entity's lazy loading feature by setting the lazy attribute of 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 to (1) at the time, Hibernate did not initiate a query on the data, if we are at this time through some debugging tools (such as JBuilder2005's Debug tool), to observe this time the user object's memory snapshots, we will be surprised to find that at this time, the return of the possibility of User$$ EnhancerByCGLIB$$bede8986 type of object, and its properties are null, this is how? Remember that I have spoken earlier session.load () method, will return the entity object of the proxy class object, the type of object returned here is the User object of the proxy class object. In Hibernate through the use of CGLIB, to achieve the dynamic construction of a target object proxy class object, and in the proxy class object contains all the properties and methods of the target object, and all attributes are assigned the value of null. through the debugger to display a snapshot of memory, we can see that at this time the real User object, is contained in the proxy object of CGLIB$ CALBACK_0.target property of the proxy object, when the code runs to (2) at this time to call user.getName() method, this time through the callback mechanism conferred by the CGLIB, in fact, call CGLIB $CALBACK_0.getName() method, when the call of this method, Hibernate will first check the CGLIB $CALBACK_0.target property is null, if not null, then call the getName method of the target object, if it is null, then it will initiate a database query to generate a SQL statement similar to this one: select * from user where id='1'; to query the data and construct the target object and assign it to the CGLIB$CALBACK_0.target property.

In this way, with an intermediate proxy object, Hibernate implements deferred loading of entities, and only when the user actually initiates the action of obtaining the properties of the entity object, does it actually initiate the database query operation. So the delayed loading of entities is accomplished with through an intermediate proxy class, so only the session.load() method will utilize the entity delayed loading, because only the session.load() method will return the proxy class object of the entity class.

B, collection type of delayed loading :

In Hibernate's delayed loading mechanism for the collection type of application, the significance of the most significant, because it is possible to make a substantial improvement in performance, for which Hibernate has carried out a large number of efforts, including an independent implementation of the JDK Collection, we are in the one-to-many associations, the Set collection defined to hold the associated objects is not java.util.Set type or its subtypes, but net.sf.hibernate.collection.Set type, through the use of a custom implementation of the collection class, Hibernate implements a delayed loading of the collection type. In order to use deferred loading for collection types, we must configure the section of our entity class on associations 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-many class= "com.neusoft.entity.Arrderss"/>

</set>

</class>

</hibernate-mapping> ;

Enable the delayed loading feature for collection types by setting the lazy attribute of the <set> element to true. 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=(Address)it.next();

System.out. println(address.getAddress());

}

When the program executes to (1), it will not initiate a query on the associated data to load the associated data, and only when it runs to (2), the real data read operation will start, and Hibernate will find the eligible entities based on the data in the cache. index, to find the eligible entity objects.

Here we introduce a new concept - data index, below we will first pick up what is a data index. In Hibernate in the collection type of cache, is divided into two parts of the cache, the first cache collection of all entities in the id list, and then cache entity objects, these entity objects id list, is the so-called data index. When looking for the data index, if the corresponding data index is not found, then a select SQL will be executed to get the qualified data and construct the entity object collection and data index, and then return the collection of entity objects, and the entity objects and data index into the Hibernate cache. On the other hand, if the corresponding data index is found, the id list is taken from the data index, and then the corresponding entity is looked up in the cache according to the id, and if it is found, it is returned from the cache, and if it is not found, the select SQL query is initiated. Here we see another issue that may have an impact on performance, which is the caching policy for collection types. 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-many class="com.neusoft.entity.Arrderss"/>

</set>

</class>

</hibernate-mapping>

Here we have applied <cache usage="read-only "/> configuration, if you use this strategy to configure the collection type, Hibernate will only cache the data index and not the entity objects in the collection. As configured above we run the following code:

User user=(User)session.load(User.class, "1");

Collection addset=user.getAddresses ();

Iterator it=addset.iterator();

while(it.hasNext()){

Address address=(Address)it.next();

System.out. println(address.getAddress());

}

System.out.println("Second query......"); < /p>

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

}

Running this code will 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 see that when the second time the query is executed, two query operations on the address table are executed, why is this so? This is because when the entity is loaded for the first time, according to the configuration of the collection type caching policy, only the collection data index is cached, but not the entity objects in the collection, so when the entity is loaded again for the second time, Hibernate finds the data index of the corresponding entity, but according to the data index, it cannot find the corresponding entity in the cache, so Hibernate initiates two select SQL queries based on the found data index, which results in a waste of performance, how can we avoid this situation? We must specify a caching policy for entities in the collection type, so 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-many class="com.neusoft.entity.Arrderss"/>

</set>

</class>

</hibernate-mapping>

This time, Hibernate will also cache the entities in the collection type, and if you run the above code again based on this configuration, you'll get an output similar to this one

Select * from user where id='1';

Select * from address where user_id='1';

< p>Tianjin

Dalian

Second query......

Tianjin

Dalian

There will be no more querying SQL statements based on the data indexes at this point, because at this point it is possible to get the entity objects stored in the collection type directly from the cache.

C. Delayed loading of attributes:

In Hibernate3, a new feature was introduced - delayed loading of attributes, a mechanism that in turn provides a powerful tool for obtaining high-performance queries. Earlier when we talked about big data object reading, there is a resume field in the User object, which is a java.sql.Clob type and contains the user's resume information, when we load the object, we have to load this field every time, regardless of whether we really need it or not, and the reading of this big data object itself will bring a lot of performance overhead. In Hibernate 2, we could only solve this problem by breaking down the User class through the granularity of faceted performance breakdown that we talked about earlier (please refer to that section for a discussion), but in Hibernate 3 we can get the ability to read the data of this field only when we really need to manipulate it, through the mechanism of delayed loading of properties. To do this we must configure our entity 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>

The delayed loading of properties is enabled by setting true to the lazy attribute of the <property> element. In Hibernate 3, in order to achieve the delayed loading of properties, class enhancers are used to enhance the entity classes' In Hibernate3, in order to achieve the delayed loading of attributes, the class enhancer is used to enhance the entity class Class file, through the enhancement of the enhancer, the CGLIB callback mechanism logic, added to the entity class, where we can see that the delayed loading of attributes is still realized through CGLIB. CGLIB is an open source project of Apache, the library can manipulate the bytecode of the Java class, according to the bytecode to dynamically construct the object of the class that meets the requirements. The following is an example of how to use CGLIB. According to the above configuration we run the following code:

String sql="from User 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 execution reaches the point at (1), an SQL statement similar to the following is generated. SQL statement:

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

This time Hibernate will retrieve all the field data corresponding to the non-delayed load attributes of the User entity. at (2), an SQL statement similar to the following is generated:

Select resume from user where id='1';

This initiates a real read operation on the resume field data.