標籤:blog http java get strong 檔案
Inverse屬性
一、Inverse是hibernate雙向關係中的基本概念。inverse的真正作用就是指定由哪一方來維護之間的關聯關係。當一方中指定了“inverse=false”(預設),那麼那一方就有責任負責之間的關聯關係,說白了就是hibernate如何產生Sql來維護關聯的記錄!
Hibernate僅僅按照主控方對象的狀態的變化來同步更新資料庫。按照原來的對應檔,people.getAddresses().add(address),即主控方對象的狀態發生了改變,因此資料庫會跟著對象狀態的變化來同步更新資料庫;而address.setPeople(people),即被控方對象的狀態發生了改變,它是不能觸發對象和資料庫的同步更新的。
(執行個體1): 舉個最簡單的一對多父子關係。那麼代碼就寫成:
[java] view plaincopyprint?
1 Parent p= newParent();
2 Child c= newChild();
3 c.setParent(p); //維護父子之間關係
4 p.getChildren().add(c);
5
6 session.save(p);
7 session.flush();
對應檔配置:
[html] view plaincopyprint?
8 父親中的關係映射
9 {set name="children" lazy="true" inverse="true"}
10 {key column="parent_id"/}
11 {one-to-many class="test.Child"/}
12 {/set}
13
14 兒子中關係映射
15 {many-to-one name="parent" column="parent_id" not-null="true"/}
注意:{many-to-one}總是設成“inverse=false”的,而且這個屬性在Mapping中是不存在的!
這樣啟動並執行下來的結果就是:
[sql] view plaincopyprint?
16 Hibernate: insert into parent (id) values(?)
17 Hibernate: insert into child (parent_id, id) values (?, ?)
那麼假如c.setParent(p)注釋掉,結果就是:
[sql] view plaincopyprint?
18 Hibernate: insert into parent (id) values(?)
=================================================== (執行個體2): 一個Person可以參加多個Event,一個Event有多個Person參加。對應檔如下:
[html] view plaincopyprint?
19 <!-- Person.hbm.xml -->
20 <hibernate-mapping package="events">
21 <class name="Person" table="person">
22 <id name="id" column="person_id">
23 <generator class="native"/>
24 </id>
25 <property name="age" length="0"/>
26 <property name="firstname"/>
27 <property name="lastname"/>
28 <set name="events" table="person_event">
29 <key column="person_id"/>
30 <many-to-many column="event_id" class="events.Event"/>
31 </set>
32 </class>
33 </hibernate-mapping>
34
35 <!-- Event.hbm.xml -->
36 <hibernate-mapping>
37 <class name="events.Event" table="events">
38 <id name="id" column="event_id">
39 <generator class="native"/>
40 </id>
41 <property name="date" column="events_date" type="timestamp"/>
42 <property name="title" column="events_title"/>
43 <set name="participants" table="person_event" inverse="true">
44 <key column="event_id"/>
45 <many-to-many column="person_id" class="events.Person"/>
46 </set>
47 </class>
48 </hibernate-mapping>
inverse=true的含義: 由雙向關聯另一方維護該關聯,己方不維護該關聯(只能進行查詢操作)。在上述代碼中,由Person方維護該<many-to-many>關係,範例程式碼如下(以向Person參與的Event中加入新的Event為例):
[java] view plaincopyprint?
49 Session session =HibernateUtil.getSessionFactory().getCurrentSession();
50 session.beginTransaction();
51 Person p =(Person) session.load(Person.class,personId);
52 Event e = (Event) session.load(Event.class, eventId);
53 p.getEvents().add(e);//執行該代碼時,hibernate會向中間表 person_event中插入person_id和event_id記錄,如果換成e.getParticipants().add(p)的話,該代碼將不會被執行,即hibernate不會向表person_event中插入記錄。
54 session.getTransaction().commit();
要注意的一點:在雙向關聯的關係中,映射的column(和table)的值要一致(即要用相同的表名和列名),不然設定為inverse="true"的這方將失去這個雙向關係,而變成了一個單向關聯。
二、Inverse和Cascade的比較
Inverse:負責控制關係,預設為false,也就是關係的兩端都能控制,但這樣會造成一些問題,更新的時候會因為兩端都控制關係,於是重複更新。一般來說有一端要設為true。
Cascade:負責控制關聯對象的級聯操作,包括更新、刪除等,也就是說對一個對象進行更新、刪除時,其它對象也受影響,比如我刪除一個對象,那麼跟它是多對一關聯性的對象也全部被刪除。
舉例說明區別:刪除“一”那一端一個對象O的時候,如果“多”的那一端的Inverse設為true,則把“多”的那一端所有與O相關聯的對象外鍵清空;如果“多”的那一端的Cascade設為Delete,則把“多”的那一端所有與O相關聯的對象全部刪除。