Inverse是hibernate雙向關系中的基本概念inverse的真正作用就是指定由哪一方來維護之間的關聯關系當一方中指定了inverse=false(默認)那麼那一方就有責任負責之間的關聯關系說白了就是hibernate如何生成Sql來維護關聯的記錄
Hibernate僅僅按照主控方對象的狀態的變化來同步更新數據庫按照原來的映射文 件peoplegetAddresses()add(address)即主控方對象的狀態發生了改變因此數據庫會跟著對象狀態的變化來同步更新 數據庫而addresssetPeople(people)即被控方對象的狀態發生了改變它是不能觸發對象和數據庫的同步更新的
(實例)
舉個最簡單的一對多父子關系那麼代碼就寫成
父親中的關系映射
{set name=children lazy=true inverse=true}
{key column=parent_id/}
{onetomany class=testChild/}
{/set}
兒子中關系映射
{manytoone name=parent column=parent_id notnull=true/}
Parent p = new Parent()
Child c = new Child()
csetParent(p) //維護父子之間關系
pgetChildren()add(c)
sessionsave(p)
sessionflush()
注意{manytoone}總是設成inverse=false的而且這個屬性在Mapping中是不存在的!
這樣運行的下來的結果就是
Hibernate: insert into parent (id) values (?)
Hibernate: insert into child (parent_id id) values (? ?)
那麼假如csetParent(p)注釋掉結果就是
Hibernate: insert into parent (id) values (?)
===================================================
(實例)
一個Person可以參加多個Event一個Event有多個Person參加
映射文件如下
<! Personhbmxml >
<hibernatemapping package=events>
<class name=Person table=person>
<id name=id column=person_id>
<generator class=native/>
</id>
<property name=age length=/>
<property name=firstname/>
<property name=lastname/>
<set name=events table=person_event>
<key column=person_id/>
<manytomany column=event_id class=eventsEvent/>
</set>
</class>
</hibernatemapping>
<! Eventhbmxml >
<hibernatemapping>
<class name=eventsEvent table=events>
<id name=id column=event_id>
<generator class=native/>
</id>
<property name=date column=events_date type=timestamp/>
<property name=title column=events_title/>
<set name=participants table=person_event inverse=true>
<key column=event_id/>
<manytomany column=person_id class=eventsPerson/>
</set>
</class>
</hibernatemapping>
inverse=true的含義 由雙向關聯另一方維護該關聯己方不維護該關聯(只能進行查詢操作)在上述代碼中由Person方維護該<manytomany>關系示例代碼如下(以向Person參與的Event中加入新的Event為例)
Session session = HibernateUtilgetSessionFactory()getCurrentSession()
sessionbeginTransaction()
Person p = (Person) sessionload(Personclass personId)
Event e = (Event) sessionload(Eventclass eventId)
pgetEvents()add(e)//執行該代碼時hibernate會向中間表 person_event中插入person_id和event_id記錄如果換成egetParticipants()add(p)的話該代碼將不會被執行即hibernate不會向表person_event中插入記錄
sessiongetTransaction()commit()
要注意的一點在雙向關聯的關系中映射的column(和table)的值要一致(即要用相同的表名和列名)不然設置為inverse=true的這方將失去這個雙向關系而變成了一個單向關聯
二Inverse和Cascade的比較
Inverse:負責控制關系默認為false也就是關系的兩端都能控制但這樣會造成一些問題更新的時候會因為兩端都控制關系於是重復更新一般來說有一端要設為true
Cascade:負責控制關聯對象的級聯操作包括更新刪除等也就是說對一個對象進行更新刪除時其它對象也受影響比如我刪除一個對象那麼跟它是多對一關系的對象也全部被刪除
舉例說明區別刪除一那一端一個對象O的時候如果多的那一端的Inverse設為true則把多的那一端所有與O相關聯的對象外鍵清空如果多的那一端的Cascade設為Delete則把多的那一端所有與O相關聯的對象全部刪除
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28235.html