Functions of one-to-multiple bidirectional hibernate Association and Inverse
When testing the one-to-multiple bidirectional Association ing of hibernate, it encountered an interesting problem, which is directly related to the inverse attribute.
1. People. HBM. xml
<Hibernate-mapping default-Lazy = "false">
<Class name = "com. Persistent. People" table = "people">
<ID name = "ID" column = "peopleid" unsaved-value = "0">
<Generator class = "increment">
</Generator>
</ID>
<Property name = "name" column = "name"> </property>
<Set name = "addresses" cascade = "Save-Update">
<Key column = "peopleid" not-null = "true"/>
<One-to-operate class = "com. Persistent. Address"/>
</Set>
</Class>
</Hibernate-mapping>
2. Address. HBM. xml
<Hibernate-mapping>
<Class name = "com. Persistent. Address" table = "Address">
<ID name = "ID" column = "addressid" unsaved-value = "0">
<Generator class = "increment">
</Generator>
</ID>
<Role-to-one name = "people" column = "peopleid" insert = "false" update = "false"> </role-to-one>
<Property name = "addressname" column = "addressname"> </property>
<Property name = "codenumber" column = "codenumber"> </property>
</Class>
</Hibernate-mapping>
3. People. Java and address. Java
Public class people ...{
Private long ID;
Private string name;
Private set addresses = new hashset ();
...
}
Public Class address ...{
Private long ID;
Private people;
Private string addressname;
Private string codenumber;
...
}
4. Database Structure
People table: {peopleid, name}
Address Table: {addressid, peopleid, addressname, codenumber}
5. Test code
People = new people ();
People. setname ("Linda ");
Address = new address ();
Address. setaddressname ("Yunnan ");
Address. setcodenumber ("564123 ");
Address. setpeople (people );
People. getaddresses (). Add (Address );
Session session = hibernatesessionfactory. getsession ();
Session. begintransaction ();
Session. Save (people );
Session. gettransaction (). Commit ();
6. Running result
The above test code runs correctly:
Hibernate: Select max (peopleid) from people
Hibernate: Select max (addressid) FROM address
Hibernate: insert into people (name, peopleid) values (?, ?)
Hibernate: insert into address (addressname, codenumber, peopleid, addressid) values (?, ?, ?, ?)
Hibernate: Update address set peopleid =? Where addressid =?
If you rewrite the ing of people. HBM. xml:
<Set name = "addresses" cascade = "Save-Update" inverse = "true">
<Key column = "peopleid" not-null = "true"/>
<One-to-operate class = "com. Persistent. Address"/>
</Set>
The difference is that inverse = "true" is added, and the result is:
Hibernate: Select max (peopleid) from people
Hibernate: Select max (addressid) FROM address
Hibernate: insert into people (name, peopleid) values (?, ?)
Hibernate: insert into address (addressname, codenumber, addressid) values (?, ?, ?)
As you can see, the peopleid is not written to the associated address, and the peopleid field of the corresponding record in the database address table is blank.
7. Analysis
In hibernate, the term inverse indicates a reversal. In the association relationship, inverse = "false" is the primary control, and the primary control is responsible for maintaining the object Association. Therefore, after the above ing file is changed, address is the main control, and people is the control, but the test code only performs a save operation session. save (people), which is for people, so the address cannot be saved in cascade mode correctly. In the original ing file (although not explicitly specified, Hibernate defaults to inverse = "false"), people is the primary control. Therefore, when people is saved, it will ensure that the associated address is properly saved.
That is to say, Hibernate only updates the database synchronously according to the state changes of the master control object. According to the original ing file, people. getaddresses (). add (address), that is, the status of the master control object has changed, so the database will update the database along with the changes in the object status; and address. setpeople (people), that is, the state of the object to be prosecuted has changed. It cannot trigger the simultaneous update of the object and the database.