Understanding of cascade and inverse in hibernate.
Which hibernate book did you buy? Sun weiqin is proficient in hibernate, or is it just that hibernate...
I have bought both of them. In general, it is okay. However, in some cases, it is relatively simplified, such as the inverse attribute.
The two attributes are the most difficult to understand in learning hibernate.
(When I first studied hibernate, I found many articles about these two attributes on the Internet, but many of them are post posts... Another thing is to move the app in the book ~~ -_-!!!)...
Example: If inverse is set to false, the relationship is maintained by the primary prosecution...
Because I am also a beginner... In addition, the language level is low... I don't understand what it means to maintain a relationship ~
Tip:
(1) If you do not know the one-to-least or least-to-one concept of hibernate.
(2) If you do not understand hibernate's concept of "free State", "persistent State", and "Free State.
(3) If you do not understand the concept of "dirty data" in hibernate.
(4) If you have no preliminary knowledge about session caching in hibernate.
(When saving is called in hibernate to store data, the "Data Object (VO)" of the database is not immediately inserted into the session cache of hibernate .)
In the above four tips, if you are not clear about one of them. If you want to learn more.
Otherwise, you may be unable or difficult to understand the two attributes of cascade or inverse.
Prime Minister cascade and inverse are actually two completely different attributes. To learn about their respective "purposes and differences", see the following introduction:
There are two tables:
(1) Class (class table)
Field:
CID varchar (32) primary key not-null (class ID)
Cname varchar (16) Not-null (class name)
(2) student (student table)
Field:
Sid varchar (32) primary key not-null (student ID)
Sname varchar (16) Not-null (Student name)
Class_id varchar (32) Not-null (student's class)
A class corresponds to multiple student, so the class table is "one-to-one-class ".
Student is the role-to-one.
// -------- Class code --------
Public class implements .....
{
Private cid = "";
Private cname = "";
Private students = java. util. hashmap ();
// Omit the corresponding geter setter
}
// -------- Class. HBM. xml --------
<Hibernate-mapping>
<Class name = "LCX. VO. Class" table = "class"
Catalog = "Demo">
<ID name = "CID" type = "Java. Lang. String">
<Column name = "CID" length = "32"/>
<Generator class = "UUID. Hex"/>
</ID>
<Property name = "name" type = "Java. Lang. String">
<Column name = "cname" length = "16" not-null = "true"/>
</Property>
<Set name = "Students" table = "student" cascade = "Save-Update">
<Key column = "class"/>
<One-to-learn class = "LCX. VO. Student"/>
</Set>
</Class>
</Hibernate-mapping>
// -------- Student class code ;*******
Public class student implements .....
{
Private SID = "";
Private sname = "";
Private class = NULL;
// Omit the corresponding geter setter
}
// Student. HBM. xml
<Hibernate-mapping>
<Class name = "LCX. VO. Student" table = "student" catalog = "Demo">
<ID name = "CID" type = "Java. Lang. String">
<Column name = "Sid" length = "32"/>
<Generator class = "UUID. Hex"/>
</ID>
<Role-to-one name = "class"
Class = "LCX. VO. Class"
Column = "class_id"
Not-null = "true"
/>
</Class>
</Hibernate-mapping>
(1) Introduction to cascade:
When hibernate persists a "temporary object (also called a free-State object)", in the default situation (I .e., when the cascade attribute is not set or cascade = none ), hibernate does not automatically "Persist other temporary objects associated with it.
What do the above statements mean? What is a temporary object that cannot be automatically "persistently" associated?
See the following code:
// Create a temporary object (also called a free-State object)
// This class is not included in session cache management by hibernate.
Class class = new class ();
// Class. ID is automatically generated
Class. setname ("first-year class 1 ");
Student Stu = new student ();
// Student. ID is automatically generated
Stu. setname ("White Rabbit ");
Stu. setclass (class );
// The Key is here...
Class. getstudents (). Add (Stu );
Session. Save (class );
// Submit
// Note: In the class. HBM. xml file, cascade = "Save-Update" and the inverse attribute is not set, that is, inverse = false;
// If you enable the hql statement display function of hibernate, the console displays the following three hql statements:
//----------------------------------------********
Insert into demo. Class (CID, cname) values (66666666666666666666666666666666, Class 1, Grade 1)
Insert into demo. Student (SID, sname, class_id) values (88888888888888811cb2e04c88888888, white rabbit, 66666666666666666666666666666666)
Update demo. Student set class_id = 66666666666666666666666666666666 where Sid = 888888888888811cb2e04c88888888
//----------------------------------------********
Why are these three hql statements displayed? Let's analyze them one by one:
1st hql statements:
In fact, the first hql is better understood,
When we call session. Save (class) and submit it in hibernate,
We will find that there is a "new" data to be inserted (insert), so we will insert this new class record to the class table.
2nd hql statements:
Note:
Why is an insert statement displayed here? Insert data to the student table.
In the above Code, we didn't write statements like "session. Save (student.
Why?
In fact, this is the reason: On the class end, we set "cascade Update" (that is, cascade = "Save-Update "),
That is to say, when hibernate inserts a "new" Object Record into the class table, it will check the attribute associated with the "Class Object" (that is, the attribute corresponding to the <set> ), whether a change has occurred. If a change has occurred, the content is set according to "cascade ".
.
What does the above sentence mean?
In your words, "people" are:
Because class. getstudents (). Add (Stu) is called );
Therefore, when hibernate inserts a class object, it finds that the class object, the associated set, has
Because the class end has set "cascade attribute cascade", when inserting this "New Class Object, they also insert other objects inside them that belong to the "free state" and their corresponding tables.
Still do not understand... You can check it out. Sun weiqin's "proficient in hibernate" is on the 149th page of the book.
But about inverse... I wrote something else, if the language is not good... It's hard to understand ~
3rd hql statements:
The third hql statement is an update statement. Is it confusing ....
The Hibernate brain is in the water. How can it survive? Repeat and update records?
Assume that the invser attribute in the configuration document of the class is set to true (that is, inverse = true)
After executing the above program, we found that it would become two insert statements ..... (Update is missing ...)
It seems that the third update statement is closely related to inverse (he has a leg ~).
So next we will introduce the inverse attributes:
When you call the class. getstudents (). Add (Stu) method to add an object,
(That is, add a student (add (Stu) to the Set (that is, the set returned by calling the getstudents method) to which the Class Object belongs. That is to say, the newly added student object (Stu ),
The student. class_id field "required" must be equal to the primary key (class. CID) of the "added class ).
In terms of database, that is, the class_id field of the newly added student must be associated with the CID field of the class ".)
Because of this: Hibernate is "afraid" when performing "class. getstudents (). Add (Stu)" operations,
Unexpected situation (for example, Stu. getclass = NULL, that is, Stu does not belong to the class ),
That is, student and class have different foreign keys.
So the redundant update statement appears. That is, one-to-minus (class end) actively maintains child. class_id
So that is to say, if Hibernate is afraid of errors, it will give you an additional useless update statement to ensure that all student in the class "set" is added.
Both are associated with a foreign key of the class.
In mandarin:
Class 1 a year. getstudents (). Add (rabbit );
Class 1 a year. getstudents (). Add (White Rabbit );
That is to say, whether it's a white rabbit or a white rabbit
If they do not have their own class,
The class teacher in Class 1 will invite them to become Class 1 in a year ~.
That is to say, the class teacher of Class 1 invites the students rather than the students to come by themselves ~~~ So the efficiency is also reduced ....
Therefore, we usually set a pair of multiple-port invser to true, that is, do not allow the master to maintain primary key associations,
(That is, ask the students to find their own classes)
To put it bluntly, the one-to-one terminal does not need to manage the primary and foreign key constraints of the newly added object.
Set the invser of one-to-second (class) to true.
(That is, when student is added to the class. getstudents set, the corresponding foreign key is not updated automatically ),
Set it manually on student.
For example:
Student. setclass (class );
Session. Save (student );
In this way, you can manually set student to be associated with the class ....
Therefore, the above program is best written as follows:
Class class = new class ();
Class. setname ("first-year class 1 ");
Session. Save (class );
Student Stu = new student ();
Stu. setname ("White Rabbit ");
Stu. setclass (class );
Session. Save (class );
/*
Add content to the class set. Database Operations (update) are not performed ).
Only the data image in the session cache is updated.
The advantage of doing so is that not only the update statement is reduced,
The session cache is also updated.
------------------------
In the original:
When one-to-Train Ends inverse = false, although the class set in the seesion cache is also updated,
But there are redundant updates.
*/
Class. getstudents (). Add (Stu );
// Submit
Summary:
When inverse is set to false and "new object (I .e. free State object)" is added to the join set at the one-to-one end,
Hibernate will automatically update the foreign key of the "just arrived" "Free State object.
(If you add a "Persistent Object" to the collection added to the one-to-one terminal, no update will occur (because it has been persisted ), unless you change the foreign key corresponding to the persistent object... In that case... Heheh ~~~
You can give it a try. It should not report an error. You can do it as an exercise to deepen the understanding of the two attributes cascade and inverse)
// If you have understood the above content. Let's take a look at the following.
Assume that cascade in the HBM. xml file of one-to-classes (that is, class) is removed or cascade = "NONE" is removed ".
So what will happen to the above Code.
Two hql statements and a bunch of exceptions are displayed.
Insert into demo. Class (CID, cname) values (66666666666666666666666666666666, Class 1, Grade 1)
Update demo. Student set class_id = 66666666666666666666666666666666 where Sid = 888888888888811cb2e04c88888888
Hibernate into tinon ......................................
Compared with cascade when "Save-Update" is set, one insert statement is missing and some exceptions are added.
Which insert statement is missing?
Is this:
Insert into demo. Student (SID, sname, class_id) values (88888888888888811cb2e04c88888888, white rabbit, 66666666666666666666666666666666)
The reason for this is that you have seen it for a long time.
Because I didn't set cascade for the class, when saving (class), the associated "Free State object" is not automatically persisted.
However, because the inverse of the class is false, the class is automatically maintained and the foreign key of the new student.
So it will appear. If there is no insert, update is required ....
Then exception occurs.