hibernate cascade 是 @OneToOne @OneToMany @ManyToOne @ManyToMany等注解的属性,表示级联操作。

  /**
* (Optional) The operations that must be cascaded to
* the target of the association.
*
* <p> By default no operations are cascaded.
*/
CascadeType[] cascade() default {};

谷歌翻译对注释的翻译

必须级联到关联目标的操作。默认情况下没有级联操作。

这里解释一下,级联的意思是:本实体做了什么事,也要拉上 另一个关联的实体,导致另一个实体跟着做事情。就是说我删除了,你也得删除! 关联目标,指的是 关联的那个实体。

在有中间关系表的情况下,比如 user/role/user_role 这三张表,只对应User/Role两个实体对象就够了!中间表是由User对象或者Role对象维护的,不用另外新建user_role的实体!

user

id name

role

id name

user_role

user_id role_id

@Table(name = "user")
@Entity
public class User
{
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "user_role", joinColumns = {@JoinColumn(name= "user_id")}, inverseJoinColumns = {@JoinColumn(name = "role_id")})
private Set<Role> roles; //get set ...
}
@Entity
@Table(name = "role")
public class Role
{ @ManyToMany(fetch= FetchType.LAZY)
@JoinTable(name = "user_role", joinColumns = {@JoinColumn(name= "role_id")}, inverseJoinColumns = {@JoinColumn(name = "user_id")})
private Set<User> users; // get set ... }

上述是对user,role多对多的关联关系的配置。cascade没有写,即是默认值,就是不级联的意思。

不级联就是说,比如在User类中,@ManyToMany没有写cascade就是说,User的操作不影响Role的操作,也就是说针对user表的操作不影响role表的记录。这个和user_role关系表没关系!user_role表的映射关系的维护,和cascade写不写,写什么值一点关系都没有!hibernate会给你维护好关系表的记录的,经测试是先删除关系记录,再插入关系记录。

如果,你发现User针对Role属性的cascade没有写,但是修改了role的值,确发生变更了,打印出sql语句,也发现还是级联更新了,咋回事?

这个我也郁闷了好久,hibernate真心不好用,太复杂了。经过苦心调试终于明白了。不是cascade不写没有用,而是你对role的变更是不是先查询出来的持久对象的操作。这样的操作是针对Role持久化对象的修改,和级联没关系,就是说你直接修改了role对象,当然更新了值!

Set<Role> roles = new HashSet<>();
for (Long roleId : roleIds)
{
Role role = roleDAO.get(Role.class, roleId);
role.setName(role.getName()+"_1"); //测试级联
roles.add(role);
}
user.setRoles(roles);
userDao.saveOrUpdate(user);

上述代码,保存user的时候,即使cascade没有写,可是role记录还是被改变了!原因就是,你通过roleId得到Role的时候,得到的是Role持久化对象,然后你改变了Role的值,那role记录肯定变更了!这个变更和cascade没有关系,是你自己变更的,能怪谁!请看下述代码

Set<Role> roles = new HashSet<>();
for (Long roleId : roleIds)
{
Role role = roleDAO.get(Role.class, roleId);
role.setName(role.getName()+"_1"); //测试级联
session.evict(role); //使持久化对象游离
roles.add(role);
}
user.setRoles(roles);
userDao.saveOrUpdate(user);

这里就增加了一句代码,再运行,你会发现,Role值改变了,确实没有使role记录发生变更,这说明cascade不写有用了。这时,你把User类下roles属性上的casecase改为CascadeType.ALL,再运行你会发现,role记录又改变了,那这次role的变更才是真正因为是cascade的作用!

总结:

1.hibernate实体关系中,cascade属性表示 实体的操作是否 级联 到 关联的实体, 和中间表无关。

2.无论cascade写不写,写什么, 中间表都将被hibernate很好的维护了。

3.cascade不写,没有生效,可能是因为你直接对 关联的实体(持久化的对象) 进行操作了,游离化的 对象就不会有事!

所以说,如果你如果不想让Role的修改影响到User,那你cascade就不要写,针对User的操作也要注意不要使用持久化的对象(get,load得到的对象,hql得到的是游离化的对象),反之亦然。不用担心中间表的关系维护! 如果你想让Role的修改影响到User,那你就写上cascade的值,级联就生效了(user对象管它是持久对象还是游离对象)!

附录:

/**
* Defines the set of cascadable operations that are propagated
* to the associated entity.
* The value <code>cascade=ALL</code> is equivalent to
* <code>cascade={PERSIST, MERGE, REMOVE, REFRESH, DETACH}</code>.
*
* @since Java Persistence 1.0
*/
public enum CascadeType { /** Cascade all operations 级联所有操作 */
ALL, /** Cascade persist operation 级联新增 */
PERSIST, /** Cascade merge operation 级联更新或者新增 */
MERGE, /** Cascade remove operation 级联删除 */
REMOVE, /** Cascade refresh operation 级联刷新 */
REFRESH, /**
* Cascade detach operation
* 级联分离
* @since Java Persistence 2.0
*
*/
DETACH
}

hibernate cascade的真正含义的更多相关文章

  1. hibernate cascade=CascadeType.All

    因为时间关系,我在这里测试的环境是一对多的关系里面用到的注解方式的级联,网上也有很多贴子,我也看过了,但是呢,我还是自己总结一下吧,这觉得级联是单向的,不是双向的,意思就是说,我们在设置两个类的对象之 ...

  2. Hibernate Cascade & Inverse

    Cascade - 修改实体表 Inverse - 修改中间表 http://www.cnblogs.com/amboyna/archive/2008/02/18/1072260.html 1.到底在 ...

  3. Hibernate cascade级联

    cascade: 级联: 是对象的连锁操作 级联保存(一对多): 级联保存: 当保存双向关系的一方时,默认会报告错误,此时应该在customr中设置级联保存,即操作一个对象时,通过操作其他关联对象 如 ...

  4. hibernate cascade

    默认:none Cascade 属性值: none:在保存.删除修改对象的时候,不考虑其附属物的操作 save-update:在保存.更新当前对象时,级联保存.更新附属物. delete:在删除当前对 ...

  5. hibernate CasCade deleted object ould be re-saved by cascade

    这个问题个人认为看你用的那种方式,如果是注解式的 比如: @ManyToMany(cascade={CascadeType.MERGE,CascadeType.REFRESH,CascadeType. ...

  6. hibernate cascade属性

    cascade属性是存在于set标签中,用来做级联删除和保存. 它的值有以下几种: 1)默认值是none,不做级联动作: 2)save-update:级联保存 3)delete:级联删除 4)all: ...

  7. 深入理解脚本化CSS系列第二篇——查询计算样式

    × 目录 [1]getComputedStyle [2]注意事项 [3]currentStyle[4]IE 前面的话 元素的渲染结果是多个CSS样式博弈后的最终结果,这也是CSS中的C(cascade ...

  8. SQLAlchemy模型使用

    SQLAchemy模型使用 简介: SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用 ...

  9. Oracle创建表空间和表

    创建表空间和表ORACLE物理上是由磁盘上的以下几种文件:数据文件和控制文件和LOGFILE构成的oracle中的表就是一张存储数据的表.表空间是逻辑上的划分.方便管理的.数据表空间 (Tablesp ...

随机推荐

  1. form在模版中的渲 染方式

    链接:https://www.jianshu.com/p/46b2aa2d5a23 form.as_p 渲染表单为一系列的p标签,每个p标签包含一个字段: <p> <label fo ...

  2. Elasticsearch NEST使用指南:映射和分析

    NEST提供了多种映射方法,这里介绍下通过Attribute自定义映射. 一.简单实现 1.定义业务需要的POCO,并指定需要的Attribute [ElasticsearchType(Name = ...

  3. iOS 发送位置消息

    发送地理位置在社交应用里面是很常用的需求.最近也需要在自己的应用里面加入这个功能 首先我们需要获取自己的地理位置,这里用到 CLLocationManager 这个类,调用如下代码 locationM ...

  4. ubuntu 安装python3

    1.安装python3 apt-get install python3 2.安装pip3 apt-get install python3-pip 3.为python3添加包 pip3 install ...

  5. CSS 两个行内块元素,宽度相加刚好等于父盒子容器的元素,但第二个元素掉在第二行解决办法

    我们可以发现:两个行内块元素,宽度相加刚好等于父盒子容器的元素,但第二个元素掉在第二行,这是什么问题呢? 我们先来看一下效果: <!DOCTYPE html> <html lang= ...

  6. SLIP—串行线路上传输数据报的非标准协议

    目录 SLIP-串行线路上传输数据报的非标准协议 简介 历史 实用性 协议 不足之处 SLIP驱动程序 做了这么多年的程序员后,总想资源回收一下,写一点点什么,却又发现无从写起. SLIP-串行线路上 ...

  7. 最新 php oracle 数据库连接 数据库分页

    php 5连接 oracle 10g php oracle 分页 <?php//buyicode studio 20/12/2009//总记录数$sql = "select ROWNU ...

  8. Git密钥

    SSH keys SSH key 可以让你在你的电脑和Code服务器之间建立安全的加密连接. 先执行以下语句来判断是否已经存在本地公钥: 1. cat ~/.ssh/id_rsa.pub    如果你 ...

  9. [BZOJ 5074][Lydsy1710月赛]小B的数字

    传送门 \(\color{green}{solution}\) 设 \[b_{i}=2^{w_{i}},sum= \sum_{i=1}^{n}{w_{i}}\] 则对于任意\(a_{i}\)都有 \[ ...

  10. BZOJ - 2741 分块维护最大连续异或和

    题意:给定\(a[l...r]\),多次询问区间\([l,r]\)中的最大连续异或和\(a_i⊕a_{i+1}⊕...⊕a_{j},l≤i≤j≤r\) 一眼过去认为是不可做的,但题目给出\(n=1.2 ...