Load and get in session

Source: Internet
Author: User
First, get does not support lazy,load support lazy.

Second, use get to load the data, if there is no matching data, return null, and load throws an exception.

Third, the execution of load (), the first to find out whether the current object exists, if not, then query from the database, if there is no such record, throw an exception; execute get (), regardless of the current object in the session, directly from the database to query, if not exist , NULL is returned.

The load () method can return an instance of an entity's proxy class, and get () always returns only the entity class.

Example of Get:

1public void Testgetmethod () {
2 session session = NULL;
3 try {
4 session = Hibernateutils.getsession ();
5 session.begintransaction ();
6
7//immediately issue query SQL, load user object
8 User user = (user) Session.get (user.class, "402880d01b9bf210011b9bf2c2ff0002");
9 System.out.println ("User.name=" + user.getname ());
10
User.setname ("Zhang San");
Session.gettransaction (). commit ();
}catch (Exception e) {
E.printstacktrace ();
Session.gettransaction (). rollback ();
}finally {
Hibernateutils.closesession (session);
18}
19}

PS: In the execution of the 8th line of the statement, if the database has related records, the SQL statement is issued immediately, even if there is no 9th line in the User.getname () method call, if there is no matching record returns a null.

Example of the Load method:

1public void Testloadmethod () {
2 session session = NULL;
3 try {
4 session = Hibernateutils.getsession ();
5 session.begintransaction ();
6
7//Does not issue query SQL because the Load method implements lazy (lazy loading or deferred loading)
8//Lazy Load: Load (Emit SQL statement) only when the object is actually used
9//hibernate Deferred Load implementation principle is proxy mode
User user = (user) session.load (user.class, "402880d01b9bf210011b9bf2b2ff0002");
System.out.println ("user.name=" + user.getname ());
User.setname ("John Doe");
Session.gettransaction (). commit ();
}catch (Exception e) {
E.printstacktrace ();
Session.gettransaction (). rollback ();
}finally {
Hibernateutils.closesession (session);
19}
20}

PS: When executing to 10 code, there is no immediate SQL statement, because load realizes lazy delay loading, delay loading only when the object is actually used to load, issued SQL statement, the key is 11 code. If the ID inside the load method is not relevant in the database table, a objectnotfoundexception exception is emitted.

PS: You can use debug to track the changes of related variables and objects by setting breakpoints, so you can clearly understand both the load and get methods.

Hibernate,session load comes out of the object is

Persistent state: The object establishes a corresponding relationship with the database record and remains in sync. The object is bound in the persistence context, and in the future any state changes and data changes are under the management of the unit of work, which is the persistence state. Session.load The default lazy loading method provided in hibernate3.2, I think the load comes out of a proxy, also can be said to be a persistent state (oneself so understand, such as wrong please a master correct).





Understanding lazy loading is helpful for understanding lazy loading:

The lazy load mechanism is proposed to avoid some unnecessary performance overhead, so-called lazy loading is when the data is really needed to perform the data loading operation. Lazy loading of entity objects and lazy loading of collections are provided in Hibernate, and lazy loading of properties is also provided in Hibernate3. Here we describe the details of these kinds of lazy loading separately.

A, lazy Loading of entity objects:

If you want to use lazy loading on an entity object, you must configure it in the entity's mapping configuration file as follows:


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

......

</class>


Turn on the lazy-load attribute of the entity by setting the class's Lazy property 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), Hibernate does not initiate queries on the data, and if we look at the memory snapshot of the user object at this time through some debugging tools (such as the Debug tool of JBuilder2005), we will be surprised to find that the return is possible at this time user$ enhancerbycglib$ $bede 8986 types of objects, and their properties are null, what's going on? Remember before I spoke of the Session.load () method, which returns the proxy class object of the Entity object, the object type returned here is the proxy class object of the user object. In Hibernate, a proxy class object that dynamically constructs a target object is implemented by using Cglib, and all properties and methods of the target object are included in the proxy class object, and all properties are assigned null. With the memory snapshot shown by the debugger, we can see that the real user object at this point is contained in the Cglib$calback_0.target property of the proxy object, and when the code runs to (2), the User.getname () method is called, At this point the callback mechanism given by Cglib actually calls the Cglib$calback_0.getname () method, and when the method is called, Hibernate first checks whether the Cglib$calback_0.target property is null, if not NULL, The GetName method of the target object is called, and if it is empty, a database query is initiated, generating a SQL statement like this: SELECT * from user where id= ' 1 ', to query the data, construct the target object, and assign it to cglib$calback_0. The target property.

In this way, hibernate implements lazy loading of entities through an intermediary proxy object, and the database query operation is really initiated only when the user actually initiates an action that obtains the attributes of the entity object. So the lazy loading of the entity is done through the intermediate proxy class, so only the Session.load () method takes advantage of entity lazy loading, because only the Session.load () method returns the proxy class object of the entity class.

B, deferred loading of collection types:

In Hibernate's lazy loading mechanism, the significance of the application for the collection type is most significant, as this has the potential to significantly improve performance, and this is a great effort for hibernate, including the standalone implementation of the JDK collection, in a one-to-many association, Defines a set of sets used to hold the associated object, Rather than the Java.util.Set type or its subtypes, but the Net.sf.hibernate.collection.Set type, hibernate implements lazy loading of collection types by using the implementation of a custom collection class. In order to use lazy loading for a collection type, we must configure the associated parts of our entity classes as follows:


<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>


Turn on the lazy-load attribute of the collection type by setting the <set> element's lazily property 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 does not initiate a query to the associated data to load the associated data, and only when it runs to (2), the actual data read operation starts, and Hibernate finds the qualifying entity object based on the data index that matches the criteria in the cache.

Here we introduce a new concept-the data index, which we will first pick up what is the data index. When a collection type is cached in Hibernate, it is cached in two parts, first caching the list of IDs for all entities in the collection, and then caching the entity objects, which are the so-called data indexes. When looking for a data index, if no corresponding data index is found, a select SQL is executed, the data is matched, the entity object collection and the data index are constructed, the collection of entity objects is returned, and the entity object and the data index are included in Hibernate's cache. On the other hand, if the corresponding data index is found, the list of IDs is taken from the data index, and the corresponding entity is found in the cache based on the ID, if it is returned from the cache, if it is not found, the Select SQL query is initiated. Here we see another problem, which can have an impact on performance, which is the cache strategy for the collection type. If we configure the collection type as follows:


<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>


Here we apply the <cache usage= "read-only"/> Configuration, if this policy is used to configure the collection type, hibernate will only cache the data index, 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 ...");

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 give you 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 saw that when we executed the query for the second time, we performed two query operations on the Address table. This is because when the entity is loaded for the first time, based on the configuration of the collection type cache policy, the collection data index is cached only, and the entity objects in the collection are not cached, so hibernate finds the data index of the corresponding entity when the entity is reloaded the second time, but according to the data index, Instead of finding the corresponding entity in the cache, hibernate initiated two select SQL query operations based on the data index found, which creates a waste of performance and how can you avoid this situation? We must also specify a cache policy for the entities in the collection type, so we configure the collection type as follows:


<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 will also cache the entities in the collection type, and if you run the above code again based on this configuration, you will get output similar to the following:

Select * from user where id= ' 1 ';

Select * FROM address where user_id= ' 1 ';

Tianjin

Dalian

Second query ...

Tianjin

Dalian

There will be no more SQL statements to query against the data index, because entity objects stored in the collection type can be obtained directly from the cache at this time.

C, attribute lazy loading:

In Hibernate3, a new feature-deferred loading of attributes is introduced, which provides a powerful tool for obtaining high-performance queries. In the front we talked about big data object reads, there is a resume field in the user object, This field is a Java.sql.Clob type, contains the user's CV information, when we load the object, we have to load this field every time, regardless of whether we really need it, and this big data object's reading itself will bring a lot of performance overhead. In Hibernate2, we can only solve this problem by decomposing the user class with the granularity of the surface performance we've talked about (refer to the section), but in Hibernate3, we're able to use the property delay-loading mechanism to To get us to the ability to read this field data only when we really need to manipulate this field, for which we must configure our entity class as follows:


<class name= "Com.neusoft.entity.User" table= "User" >

......

<property name= "Resume" type= "Java.sql.Clob" column= "Resume" lazy= "true"/>

</class>


By setting true for the lazy property of the <property> element to enable lazy loading of the property, the class enhancer is used to harden the classes of the entity classes in Hibernate3 in order to implement deferred loading of the attributes, which is enhanced by the enhancer. The cglib callback mechanism logic is added to the entity class, where we can see the deferred loading of the properties, or the implementation through Cglib. Cglib is an open source project for Apache, which can manipulate the bytecode of Java classes and dynamically construct class objects that meet the requirements based on bytecode. 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 executed to (1), a SQL statement similar to the following is generated:

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

Hibernate retrieves the field data for all non-lazy load properties in the user entity, and when it executes to (2), a SQL statement similar to the following is generated:

Select resume from user where id= ' 1 ';



1. Load a record that does not exist
Employee Employee2 = (employee) session.load (Employee.class, New Integer (100));
Will throw net.sf.hibernate.ObjectNotFoundException.
If you do not want to throw the exception, you should use Session.get (Class clazz, Serializable ID);

2. Load a database of records that exist
1) If the session's cache is present, the reference is returned directly.
Session session = Hibernatesessionfactory.currentsession ();
Transaction tx = Session.begintransaction ();
Employee Employee1 = new Employee ();
Employee1.setage ((byte) 10);
Employee1.setbirthday (New Date ());
Employee1.setemployeename ("Hairroot");
Employee1.setgender (' m ');
Employee1.setmarried (FALSE);
Session.save (EMPLOYEE1);
System.out.println (EMPLOYEE1);

Employ1 has been saved
Employee Employee2 = (employee) session.load (Employee.class, New Integer (/*employee1.getid () */100));
System.out.println (EMPLOYEE2);
Tx.commit ();
Session.close ();

You can see that employee1 and Employee2 are the same reference. Opening show_sql=true also finds that Hibernate does not send a SELECT statement to the database.

2) If the session does not exist in the cache, a select is sent immediately.
Session session = Hibernatesessionfactory.currentsession ();
Transaction tx = Session.begintransaction ();
Employee employee = (employee) session.load (Employee.class, New Integer (100));
SYSTEM.OUT.PRINTLN (employee);
Tx.commit ();
Session.close ();

Backstage: Hibernate:select employee0_.id as id0_, employee0_.age as age0_, employee0_.birthday as birthday0_, Employee0_.employ Eename as employee4_0_, Employee0_.gender as gender0_, employee0_.married as married0_ from Mws_test_employee employee0_ W Here employee0_.id=?



A real read operation is initiated for the Resume field data.

  • Related Article

    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.