We will continue to introduce the hibernate annotation content.
1. onetoone lazy loading
When using a one-to-one annotation and using a foreign key column for object Association, you need to pay attention to the lazy loading problem. As follows:
Student table:
id int not nullname varchar(50) not nullcard_id int not null
Card table:
id int not nullcard_no varchar() not null
Student Class
public class Student {private int id;private String name;private Card card;....@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)@JoinColumn(name = "card_id")public Card getCard() {return card;}public void setCard(Card card) {this.card = card;}}
Card class
public class Card {private int id;private String cardNo;private Student student;....@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "card")public Student getStudent() {return student;}public void setStudent(Student student) {this.student = student;}}
According to the above relationship, after running the code, we will find that student can be loaded lazily when getting the card, but the card cannot be loaded lazily when getting the student. Why?
Cause: because there are no related fields in the card table, you cannot find out who owns the card from the perspective of the card table (unless the foreign key student_id of the student table is created in the card table, but because of the redundant relational fields, few people do this. [note that two tables are taken into account in the SQL join statement]. student is not the same, the student may have a card because it contains the card_id field.
For the above reason, when getting student from card, Hibernate sends an SQL statement: Select * from student where card_id =? To determine whether the card exists in the student table ?, The parameter is the ID of the card to maintain the relationship between the card and student.
There is another explanation, but we need to understand hibernate's lazy loading mechanism: proxy.
2. Lazy loading principle
Hibernate uses a proxy, and calls to the object will be accepted and processed by the proxy. hibernate can set this proxy to load data when it is called to implement delayed loading. For a ing object, either it has a value or it is null. It does not have much effect on setting up a proxy for the null value, nor can it establish a dynamic proxy for null. That is to say, when hibernate establishes a proxy for delayed loading, it should consider whether the ing object is null. If it is null, you do not need to create a proxy. You can directly set the ing value to null. If the ing object is not null, Hibernate will create a proxy object.
In short, if it is null, it cannot be loaded lazily, and it can be loaded lazily only for the proxy object.
How can we solve the above problems?
● Change the getstudent of the card class to manytoone and set unique to true. Disadvantage: You need to change the field to set <student>.
● Manually create a proxy object for student. (This is not recommended, and I have never tried it)
● Adopts the no-proxy lazy loading mechanism to enhance the class with instrument, that is, the class booster is used to enhance the binary class file. (This is rarely done and is not recommended)
Ant's build. xml script is as follows:
<?xml version="1.0" encoding="UTF-8"?><project name="hibernatelazy" default="instrument" basedir="."> <property name="lib.dir" value="./lib"/> <property name="classes.dir" value="./classes"/> <path id="lib.class.path"> <fileset dir="${lib.dir}"> <include name="**/*.jar"/> </fileset> </path> <target name="instrument"> <taskdef name="instrument" classname="org.hibernate.tool.instrument.InstrumentTask"> <classpath path="${classes.dir}"/> <classpath refid="lib.class.path"/> </taskdef> <instrument verbose="true"> <fileset dir="${classes.dir}/com/derek/known/hbm"> <include name="Knownquestions.class"/> </fileset> </instrument> </target></project>
Note:
<Property name = "Lib. dir" value = "./lib"/> JAR file path.
<Property name = "classes. dir" value = "./classes"/> compile the output path.
I set build. XML is placed in the WEB-INF directory, the output path is set to the classes directory under the directory, the bytecode file to be enhanced under the classes directory COM/Derek/known/HBM/knownquestions. class; switch to this directory under the command line and execute the ant command to generate a new knownquestions. class.
● Discard lazy loading, change to join loading policy, or use hql: From card t inner join fetch T. Student R
3. Explanation of lazy loading annotation Methods
● Fetchtype (the class corresponding to the fetch attribute in the annotation such as @ onetoone and @ onetoworkflow, without annotation)
JPA standard general load policy annotation attributes. The optional values of fetchtype have the following meanings and differences:
Fetchtype. Lazy: lazy load. It is loaded when the first access to the associated object
Fetchtype. Eager: load immediately. When querying the primary object, the associated object is loaded at the same time.
● @ Fetch
Hibernate defines a get policy for loading associations. The optional values of fetch have the following meanings and differences:
Fetchmode. Join: Always load immediately. When using an outer join query, the associated object is loaded while the fetchtype. Lazy setting is ignored.
Fetchmode. Select: supports lazy loading (unless the associated attribute lazy = false is set). When this object is loaded when each associated object is accessed, n + 1 SQL statement is generated in total.
Fetchmode. Subselect: supports lazy loading (unless the association attribute is set to lazy = false). All associated objects are loaded when the first associated object is accessed. Two SQL statements are generated cumulatively.
● @ Lazytoone
Hibernate defines the latency options associated with @ manytoone and @ onetoone. The optional lazytoone values have the following meanings and differences:
Lazytooneoption. Proxy: Agent-Based delayed loading.
Lazytooneoption. no_proxy: latency loading based on bytecode enhancement-note that you need to process bytecode enhancement during build.
Lazytooneoption. False: Non-delayed loading Association.
● @ Lazycollection
Hibernate defines the latency options associated with @ manytomany and @ onetomany. The optional value of lazycollection has the following meanings and differences:
Lazycollectionoption. true: the set is delayed and is loaded only when accessed.
Lazycollectionoption. Extra: the set is delayed, and all operations avoid loading the set as much as possible. This is especially useful for a large set because there is no need to load all elements in such a set.
Lazycollectionoption. False: the Association of Non-delayed loading.
Equivalent annotation of latency and obtaining options
Annotations |
Lazy |
Fetch |
@ [One | rule] toone] (fetch = fetchtype. Lazy) |
@ Lazytoone (proxy) |
@ Fetch (select) |
@ [One | batch] toone] (fetch = fetchtype. Eager) |
@ Lazytoone (false) |
@ Fetch (join) |
@ Manyto [one | Random] (fetch = fetchtype. Lazy) |
@ Lazycollection (true) |
@ Fetch (select) |
@ Manyto [one | batch] (fetch = fetchtype. Eager) |
@ Lazycollection (false) |
@ Fetch (join) |