发布网友 发布时间:2024-10-01 05:51
共1个回答
热心网友 时间:2024-12-12 18:12
只有 关系标记 才有cascade属性
一个操作因级联cascade可能触发多个关联操作 前一个操作叫 主控操作 后一个操作叫 关联操作
cascade属性的可能值有
all: 所有情况下均进行关联操作 即save update和delete
none: 所有情况下均不进行关联操作 这是默认值
save update: 在执行save/update/saveOrUpdate时进行关联操作
delete: 在执行delete 时进行关联操作
all delete orphan: 当一个节点在对象图中成为孤儿节点时 删除该节点 比如在一个一对多的关系中 Student包含多个book 当在对象关系中删除一个book时 此book即成为孤儿节点
级联(cascade)属性的作用
级联指的是当主控方执行操作时 关联对象(被动方)是否同步执行同一操作
pojo和它的关系属性的关系就是 主控方 被动方 的关系 如果关系属性是一个set 那么被动方就是set中的一个一个元素
比如 学校(School)有三个属性 地区(Address) 校长(TheMaster)和学生(Set 元素为Student)
执行session delete(school)时 级联决定是否执行session delete(Address) session delete(theMaster)
是否对每个aStudent执行session delete(aStudent)
具体执行什么 关联操作 是根据 主控操作 来的
主控操作 关联操作
session saveOrUpdate > session saveOrUpdate (执行saveOrUpdate实际上会执行save或者update)
session save > session saveOrUpdate
session udpate > session saveOrUpdate
session delete > session delete
主控操作和关联操作的先后顺序是 先保存one 再保存many 先删除many 再删除one 先update主控方 再update被动方
对于one to one 当其属性constrained= false (默认值)时 它可看作one to many关系
当其属性constrained= true 时 它可看作many to one关系
对many to many 它可看作one to many
比如 学校(School)有三个属性 地区(Address) 校长(TheMaster 其constrained= false )和学生(Set 元素为Student)
当执行session save(school)时
实际的执行顺序为 session save(Address);
session save(school);
session save(theMaster);
for( 对每一个student ){
session save(aStudent);
}
当执行session delete(school)时
实际的执行顺序为 session delete(theMaster);
for( 对每一个student ){
session delete(aStudent);
}
session delete(school);
session delete(Address);
当执行session update(school)时
实际的执行顺序为 session update(school);
session saveOrUpdate(Address);
session saveOrUpdate(theMaster);
for( 对每一个student ){
session saveOrUpdate(aStudent);
}
注意 update操作因级联引发的关联操作为saveOrUpdate操作 而不是update操作
saveOrUpdate与update的区别是 前者根据操作对象是保存了还是没有保存 而决定执行update还是save
extends: 实际中 删除学校不会删除地区 即地区的cascade一般设为false
另外 many to many关系很少设置cascade=true 而是设置inverse=false 这个反映了cascade和inverse的区别 见
cascade的默认值为false 所以inverse属性默认会进行 关联更新
总结 级联(cascade)就是操作一个对象时 对它的属性(其cascade=true)也进行这个操作
inverse和cascade的比较
这两个属性本身互不影响 但起的作用有些类似 都能引发对关系表的更新
inverse只对set+one to many(或many to many)有效 对many to one one to one无效
cascade对关系标记都有效
inverse对集合对象整体起作用 cascade对集合对象中的一个一个元素起作用 如果集合为空 那么cascade不会引发关联操作
比如将集合对象置为null school setStudentSet(null)
inverse导致hibernate执行:udpate STUDENT set SCHOOL_ID=null where SCHOOL_ID=?
cascade则不会执行对STUDENT表的关联更新 因为集合中没有元素
再比新增一个school session save(school)
inverse导致hibernate执行
for( 对(school的每一个student ){
udpate STUDENT set SCHOOL_ID=? where STUDENT_ID=? //将学生的school_id改为新的school的id
}
cascade导致hibernate执行
for( 对school的每一个student ){
session save(aStudent); //对学生执行save操作
}
extends:如果改变集合中的部分元素(比如新增一个元素)
inverse: hibernate先判断哪些元素改变了 对改变的元素执行相应的sql
cascade: 它总是对集合中的每个元素执行关联操作
(在关联操作中 hibernate会判断操作的对象是否改变)
两个起作用的时机不同
cascade 在对主控方操作时 级联发生
inverse: 在flush时(mit会自动执行flush) 对session中的所有set hibernate判断每个set是否有变化
对有变化的set执行相应的sql 执行之前 会有个判断 if( inverse == true ) return;
可以看出cascade在先 inverse在后
inverse 对set + one to many 和 set + many to many 起的作用不同 hibernate生成的sql不同
对one to many hibernate对many方的数据库表执行update语句
对many to many hibernate对关系表执行insert/update/delte语句 注意不是对many方的数据库表而是关系表
cascase 对set都是一致的 不管one to many还是many to many 都简单地把操作传递到set中的每个元素 所以它总是更新many
方的数据库表
建议 只对set + many to many设置inverse=false 其他的标记不考虑inverse属性 都设为inverse=true
lishixin/Article/program/Java/ky/201311/28820