hibernate中 cascade屬性詳解


 

 配置關聯時,我們考慮兩點:程序執行效率和實際業務需要,前面的例子中無論是單向的關聯還是雙向的關聯,我們都要分別對實體類使用session.save()才能將數據保存至數據庫。
問題:如果保存數據非常多,那編碼是一件恐怖的事情。
有沒有簡單的方法呢?
將<set>標簽cascade=all
總結:我們只對district對象執行了持久化操作,但是通過sql語句,我們發現street執行了持久啊操作,這就是cascade屬性的作用。當設置cascade屬性不none時,Hibernate會持久化所關聯的對象。


1.all   :對象所有操作進行級聯操作  save,update,delete
2.save-update :  執行保存和更改操作時進行級聯操作
3.delete :  執行刪除操作時進行級聯操作
4.none : 對所有操作不進行級聯操作       默認

cascade屬性的設置往往會帶來性能上的變動,請謹慎設置。
例如:對district對象進行保存或更改操作時,district對象不一定有關聯的street對象,或street對象不一定也需要更新,但是刪除district對象時同時刪除它所關聯的street對象
因此:將cascade屬性設置為all是不恰當的,應該設置為delete

Hibernate: insert into district (name, id) values (?, ?)
Hibernate: insert into street (name, district_id, id) values (?, ?, ?)
Hibernate: update street set district_id=? where id=?
1.第一條語句:比較好理解,插入新的區數據
2.第二天語句:這里為什么出現insert街道呢?我們並沒有編寫session.save(street)?
答案:其實我們在district端設置了級聯更新(cascade=”all”)
也即是說,當HIbernate在向district插入”新“對象記錄時,會檢查“district”對象所關聯的屬性(就是<set>對應的屬性)是否發生變化,如果發生變化就按設定的內容進行操作。因為調用了district.getStreet().add(street),所有Hibenate插入district時候,也一同把它所關聯的瞬時狀態的對象一同插入到對應的表中區。

Hibernate: update street set district_id=? where id=?
3.第三條語句:是update語句,為什么重復更新記錄?
答:Hibernate將district與street之間的關聯交由district來維持,就district而言,它要先儲存自己,然后儲存它所包括的多個street,之后對每一個street更新(update)對自己(district)的關聯。
就district而言,它並不知道它所包括的street是不是已存儲的對象,或者即使是已存儲對象,也不知道street表格上的district_id是不是參考至district表格的id
所以,它必須針對自己所有包括的street對象進行更新,以確保street表格上的district_id是指向自己的。

正因為如此,所以Hibernate“怕”在進行”district.getStreet().add(street)”這樣操作時,出現意外情況(如street.getClss=null,street沒有所屬的區)
存在外鍵不一致的情況。所有出現了這條多余的update語句。
也就是由one-to-many中一的一方(district端)主動維護外鍵,以保證所有包含district對象的集合里的所有street對象都要與自己(district)有外鍵關聯。
通俗講:每年開學新生報到,班級老師主動邀請同學,而不是同學自己來報到。可想而知效率怎么樣?
Hiberate有沒有提供解決這種情況的辦法呢?
當然有:那就是設置inverse屬性!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM