只有關系標記才有cascade屬性
一個操作因級聯cascade可能觸發多個關聯操作前一個操作叫主控操作後一個操作叫關聯操作
cascade屬性的可能值有
all: 所有情況下均進行關聯操作即saveupdate和delete
none: 所有情況下均不進行關聯操作這是默認值
saveupdate: 在執行save/update/saveOrUpdate時進行關聯操作
delete: 在執行delete 時進行關聯操作
alldeleteorphan: 當一個節點在對象圖中成為孤兒節點時刪除該節點比如在一個一對多的關系中Student包含多個book當在對象關系中刪除一個book時此book即成為孤兒節點
級聯(cascade)屬性的作用
級聯指的是當主控方執行操作時關聯對象(被動方)是否同步執行同一操作
pojo和它的關系屬性的關系就是主控方 被動方的關系如果關系屬性是一個set那麼被動方就是set中的一個一個元素
比如學校(School)有三個屬性地區(Address)校長(TheMaster)和學生(Set元素為Student)
執行sessiondelete(school)時級聯決定是否執行sessiondelete(Address)sessiondelete(theMaster)
是否對每個aStudent執行sessiondelete(aStudent)
具體執行什麼關聯操作是根據主控操作來的
主控操作 關聯操作
sessionsaveOrUpdate > sessionsaveOrUpdate (執行saveOrUpdate實際上會執行save或者update)
sessionsave > sessionsaveOrUpdate
sessionudpate > sessionsaveOrUpdate
sessiondelete > sessiondelete
主控操作和關聯操作的先後順序是先保存one再保存many先刪除many再刪除one先update主控方再update被動方
對於onetoone當其屬性constrained=false(默認值)時它可看作onetomany關系
當其屬性constrained=true時它可看作manytoone關系
對manytomany它可看作onetomany
比如學校(School)有三個屬性地區(Address)校長(TheMaster其constrained=false)和學生(Set 元素為Student)
當執行sessionsave(school)時
實際的執行順序為sessionsave(Address);
sessionsave(school);
sessionsave(theMaster);
for( 對每一個student ){
sessionsave(aStudent);
}
當執行sessiondelete(school)時
實際的執行順序為sessiondelete(theMaster);
for( 對每一個student ){
sessiondelete(aStudent);
}
sessiondelete(school);
sessiondelete(Address);
當執行sessionupdate(school)時
實際的執行順序為sessionupdate(school);
sessionsaveOrUpdate(Address);
sessionsaveOrUpdate(theMaster);
for( 對每一個student ){
sessionsaveOrUpdate(aStudent);
}
注意update操作因級聯引發的關聯操作為saveOrUpdate操作而不是update操作
saveOrUpdate與update的區別是前者根據操作對象是保存了還是沒有保存而決定執行update還是save
extends: 實際中刪除學校不會刪除地區即地區的cascade一般設為false
另外manytomany關系很少設置cascade=true而是設置inverse=false這個反映了cascade和inverse的區別見
cascade的默認值為false所以inverse屬性默認會進行關聯更新
總結級聯(cascade)就是操作一個對象時對它的屬性(其cascade=true)也進行這個操作
inverse和cascade的比較
這兩個屬性本身互不影響但起的作用有些類似都能引發對關系表的更新
inverse只對set+onetomany(或manytomany)有效對manytoone onetoone無效
cascade對關系標記都有效
inverse對集合對象整體起作用cascade對集合對象中的一個一個元素起作用如果集合為空那麼cascade不會引發關聯操作
比如將集合對象置為null schoolsetStudentSet(null)
inverse導致hibernate執行:udpate STUDENT set SCHOOL_ID=null where SCHOOL_ID=?
cascade則不會執行對STUDENT表的關聯更新 因為集合中沒有元素
再比新增一個school sessionsave(school)
inverse導致hibernate執行
for( 對(school的每一個student ){
udpate STUDENT set SCHOOL_ID=? where STUDENT_ID=? //將學生的school_id改為新的school的id
}
cascade導致hibernate執行
for( 對school的每一個student ){
sessionsave(aStudent); //對學生執行save操作
}
extends:如果改變集合中的部分元素(比如新增一個元素)
inverse: hibernate先判斷哪些元素改變了對改變的元素執行相應的sql
cascade: 它總是對集合中的每個元素執行關聯操作
(在關聯操作中hibernate會判斷操作的對象是否改變)
兩個起作用的時機不同
cascade在對主控方操作時級聯發生
inverse: 在flush時(commit會自動執行flush)對session中的所有sethibernate判斷每個set是否有變化
對有變化的set執行相應的sql執行之前會有個判斷if( inverse == true ) return;
可以看出cascade在先inverse在後
inverse 對set + onetomany 和 set + manytomany 起的作用不同hibernate生成的sql不同
對onetomanyhibernate對many方的數據庫表執行update語句
對manytomany hibernate對關系表執行insert/update/delte語句注意不是對many方的數據庫表而是關系表
cascase 對set都是一致的不管onetomany還是manytomany都簡單地把操作傳遞到set中的每個元素所以它總是更新many
方的數據庫表
建議只對set + manytomany設置inverse=false其他的標記不考慮inverse屬性都設為inverse=true
對cascade一般對manytoonemanytomanyconstrained=true的onetoone 不設置級聯刪除
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28820.html