Hibernate傳播性持久化攻略
本文向大家介紹Hibernate傳播性持久化(transitive persistence),可能好多人還不了解Hibernate傳播性持久化(transitive persistence),沒有關(guān)系,看完本文你肯定有不少收獲,希望本文能教會你更多東西。
對每一個對象都要執(zhí)行保存,刪除或重關(guān)聯(lián)操作讓人感覺有點麻煩,尤其是在處理許多彼此關(guān)聯(lián)的對象的時候。 一個常見的例子是父子關(guān)系??紤]下面的例子:
如果一個父子關(guān)系中的子對象是值類型(value typed)(例如,地址或字符串的集合)的,他們的生命周期會依賴于父對象,可以享受方便的級聯(lián)操作(Cascading),不需要額外的動作。
父對象被保存時,這些值類型(value typed)子對象也將被保存;父對象被刪除時,子對象也將被刪除。 這對將一個子對象從集合中移除是同樣有效:Hibernate會檢測到,并且因為值類型(value typed)的對象不可能被其他對象引用,所以Hibernate會在數(shù)據(jù)庫中刪除這個子對象。
現(xiàn)在考慮同樣的場景,不過父子對象都是實體(entities)類型,而非值類型(value typed)(例如,類別與個體,或母貓和小貓)。 實體有自己的生命期,允許共享對其的引用(因此從集合中移除一個實體,不意味著它可以被刪除), 并且實體到其他關(guān)聯(lián)實體之間默認(rèn)沒有級聯(lián)操作的設(shè)置。Hibernate默認(rèn)不實現(xiàn)所謂的可到達即Hibernate傳播性持久化(persistence by reachability)的策略。
每個Hibernate session的基本操作 - 包括 persist(), merge(), saveOrUpdate(), delete(), lock(), refresh(), evict(), replicate() - 都有對應(yīng)的級聯(lián)風(fēng)格(cascade style)。 這些級聯(lián)風(fēng)格(cascade style)風(fēng)格分別命名為 create, merge, save-update, delete, lock, refresh, evict, replicate。 如果你希望一個操作被順著關(guān)聯(lián)關(guān)系級聯(lián)傳播,你必須在映射文件中指出這一點。例如:
- <one-to-one name="person" cascade="persist"/>
級聯(lián)風(fēng)格(cascade style)是可組合的:
- <one-to-one name="person" cascade="persist,delete,lock"/>
你可以使用cascade="all"來指定全部操作都順著關(guān)聯(lián)關(guān)系級聯(lián)(cascaded)。 默認(rèn)值是cascade="none",即任何操作都不會被級聯(lián)(cascaded)。
注意有一個特殊的級聯(lián)風(fēng)格(cascade style) delete-orphan,只應(yīng)用于one-to-many關(guān)聯(lián),表明delete()操作 應(yīng)該被應(yīng)用于所有從關(guān)聯(lián)中刪除的對象。
建議:
通常在
如果子對象的壽命限定在父親對象的壽命之內(nèi),可通過指定cascade="all,delete-orphan"將其變?yōu)樽詣由芷诠芾淼膶ο?lifecycle object)。
其他情況,你可根本不需要級聯(lián)(cascade)。但是如果你認(rèn)為你會經(jīng)常在某個事務(wù)中同時用到父對象與子對象,并且你希望少打點兒字,可以考慮使用cascade="persist,merge,save-update"。
可以使用cascade="all"將一個關(guān)聯(lián)關(guān)系(無論是對值對象的關(guān)聯(lián),或者對一個集合的關(guān)聯(lián))標(biāo)記為父/子關(guān)系的關(guān)聯(lián)。 這樣對父對象進行save/update/delete操作就會導(dǎo)致子對象也進行save/update/delete操作。
此外,一個持久的父對象對子對象的淺引用(mere reference)會導(dǎo)致子對象被同步save/update。 不過,這個隱喻(metaphor)的說法并不完整。除非關(guān)聯(lián)是
如果父對象被persist(),那么所有子對象也會被persist()
如果父對象被merge(),那么所有子對象也會被merge()
如果父對象被save(),update()或 saveOrUpdate(),那么所有子對象則會被saveOrUpdate()
如果某個持久的父對象引用了瞬時(transient)或者脫管(detached)的子對象,那么子對象將會被saveOrUpdate()
如果父對象被刪除,那么所有子對象也會被delete()
除非被標(biāo)記為cascade="delete-orphan"(刪除“孤兒”模式,此時不被任何一個父對象引用的子對象會被刪除), 否則子對象失掉父對象對其的引用時,什么事也不會發(fā)生。 如果有特殊需要,應(yīng)用程序可通過顯式調(diào)用delete()刪除子對象。
***,注意操作的級聯(lián)可能是在調(diào)用期(call time)或者寫入期(flush time)作用到對象圖上的。所有的操作,如果允許,都在操作被執(zhí)行的時候級聯(lián)到可觸及的關(guān)聯(lián)實體上。然而,save-upate和delete-orphan是在Session flush的時候才作用到所有可觸及的被關(guān)聯(lián)對象上的。
本文只是大概的說明了Hibernate傳播性持久化的應(yīng)用,可能還有不足的地方,讀者可以查更多的書去了解。
【編輯推薦】