文档章节

hibernate cascade

隆回水哥
 隆回水哥
发布于 2015/03/27 11:38
字数 680
阅读 1889
收藏 2
  • 1. cascade定义级联操作,即"操作完自己"之后下一步做什么。

理解inverse中,Member与MemberCard是一对多的关系,Member级联save-update MemberCard,所以只要保存member

session.save(member);

memberCard也跟着保存了。

  • 2. 有时我们会看到这样一个级联配置:cascade="delete-orphan"。

annotation中这样配置

// orphanRemoval=true级联更新删除"脱离"的子节点
@OneToMany(mappedBy = "member", orphanRemoval=true)
@Cascade({ CascadeType.SAVE_UPDATE })
private Set<MemberCard> memberCards;

或者

// CascadeType.DELETE_ORPHAN级联更新删除"脱离"的子节点
@OneToMany(mappedBy = "member")
@Cascade({ CascadeType.SAVE_UPDATE, CascadeType.DELETE_ORPHAN })
private Set<MemberCard> memberCards;

比较新的版本,官方推荐使用orphanRemoval=true

public enum CascadeType {
    ...
    /** @deprecated use @OneToOne(orphanRemoval=true) or @OneToMany(orphanRemoval=true) */
    @Deprecated
    DELETE_ORPHAN,
    ...}

这是用于删除“脱离”的子节点。

Member member = (Member)session.get(Member.class, 1);
member.setMemberName("张三2");
Set<MemberCard> memberCards = member.getMemberCards();
// 确认会员有3张会员卡
Assert.assertEquals(3, memberCards.size());
// 从中取出一张会员卡
MemberCard memberCard = memberCards.iterator().next();
// 把这张会员卡移除掉
member.getMemberCards().remove(memberCard);
session.update(member);

从上面的代码中可以看到只update一下member,在update member之后有一条delete语句,sql输出如下:

Hibernate: select member0_.id as id2_0_, member0_.member_name as member2_2_0_ from member member0_ where member0_.id=?
Hibernate: select membercard0_.member_id as member3_2_1_, membercard0_.id as id1_, membercard0_.id as id3_0_, membercard0_.card_no as card2_3_0_, membercard0_.member_id as member3_3_0_ from member_card membercard0_ where membercard0_.member_id=?
Hibernate: update member set member_name=? where id=?
Hibernate: delete from member_card where id=?
  • 3. cascade:JPA & Hibernate annotation。

这里是很容易让人误解的地方。

JPA cascade: javax.persistence.CascadeType

public enum CascadeType { 

    /** Cascade all operations */
    ALL, 

    /** Cascade persist operation */
    PERSIST, 

    /** Cascade merge operation */
    MERGE, 

    /** Cascade remove operation */
    REMOVE,

    /** Cascade refresh operation */
    REFRESH}

Hibernate cascade:org.hibernate.annotations.CascadeType

public enum CascadeType {
    ALL,
    PERSIST,
    MERGE,
    REMOVE,
    REFRESH,
    DELETE,
    SAVE_UPDATE,
    REPLICATE,
    /** @deprecated use @OneToOne(orphanRemoval=true) or @OneToMany(orphanRemoval=true) */
    @Deprecated
    DELETE_ORPHAN,
    LOCK,
    /** @deprecated use javax.persistence.CascadeType.DETACH */
    @Deprecated
    EVICT,
    DETACH}

有时我们这样配置,这里应用的是JPA cascade

@OneToMany(mappedBy = "member", fetch = FetchType.LAZY, cascade={CascadeType.PERSIST})
private Set<MemberCard> memberCards;

保存member,发现memberCard没有跟着保存,除非使用CascadeType.ALL,否则其他的都没有用。

session.save(member);

sql输出

Hibernate: insert into member (id, member_name) values (null, ?)

但是session.persist()却可以级联保存

session.persist(member);

sql输出

Hibernate: insert into member (id, member_name) values (null, ?)
Hibernate: insert into member_card (id, card_no, member_id) values (null, ?, ?)
Hibernate: insert into member_card (id, card_no, member_id) values (null, ?, ?)
Hibernate: insert into member_card (id, card_no, member_id) values (null, ?, ?)

如果我们想session.save()方法有效果,可以使用hibernate cascade:

@OneToMany(mappedBy = "member", fetch = FetchType.LAZY)
@Cascade({ CascadeType.SAVE_UPDATE })
private Set<MemberCard> memberCards;

再试一下

session.save(member);

sql输出

Hibernate: insert into member (id, member_name) values (null, ?)
Hibernate: insert into member_card (id, card_no, member_id) values (null, ?, ?)
Hibernate: insert into member_card (id, card_no, member_id) values (null, ?, ?)
Hibernate: insert into member_card (id, card_no, member_id) values (null, ?, ?)

从上面的实践中,大概可以知道cascade的类型粗略的对应着session的一个方法。更详细的内容可以查看hibernate源码 org.hibernate.engine.Cascade/org.hibernate.engine.CascadeStyle/org.hibernate.engine.CascadingActiona

cascade vs inverse(mappedBy)

cascade说明级联操作,操作完自己之后下一步做什么;inverse说明由谁来维护外键的值。


更多参考hibernate demo

© 著作权归作者所有

共有 人打赏支持
上一篇: spring 集成 junit
下一篇: hibernate mappedBy
隆回水哥
粉丝 14
博文 49
码字总数 18518
作品 0
深圳
高级程序员
私信 提问
MySql和Hibernate中关于cascade的用法

数据库里的cascade的用法,Mysql和Hibernate里面是不相同。 在数据库里,进行增加、修改、删除记录的时候,经常会涉及到父子关系的表。 例如:有省份表和城市表,其中城市表有一个外键provi...

空云万里晴
2012/08/29
0
0
Hibernate中cascade作用

只有“关系标记”才有cascade属性; 一个操作因级联cascade可能触发多个关联操作。前一个操作叫“主控操作”,后一个操作叫“关联操作”。   cascade属性的可能值有   all: 所有情况下均...

_守望者_
2014/04/22
0
0
幽默者/hibernate mysql demo

hibernate-mysql-demo 基于maven构建的hibernate mysql demo。 基于xml、annotation的hibernate demo:其中包含one-to-one、one-to-many、many-to-many映射关系的配置。 独立的测试用例。 内...

幽默者
2015/01/26
0
0
Hibernate中inverse和cascade及相应异常处理

在hibernate中,inverse和cascade经常容易弄混淆,下面简单的说明一下两者区别。 cascade: 这里我们以annotation作为例子。 cascade={CascadeType.ALL} CascadeType是枚举类型,其取值可以是...

Sandy_wu
2013/09/02
0
0
Hibernate中的cascade和inverse

这两个属性都用于一多对或者多对多的关系中。而inverse特别是用于双向关系,在单向关系中我们并不需要。 Cascade代表是否执行级联操作,Inverse代表是否由己方维护关系。 Cascade: Cascade属...

roockee
2012/12/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

总结:volatile关键字

实现内存可见性原理: 对volatile变量执行写操作时,会在写操作之后加入一条store指令,将CPU缓存数据强制刷新到主内存中 对volatile变量执行读操作的时候,会在读操作前加入一条load指令,重...

浮躁的码农
24分钟前
0
0
OSChina 周六乱弹 —— 看见这花臂了么?赶紧叫大佬!

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @宇辰OSC :分享周华健的单曲《有没有一首歌会让你想起我》 《有没有一首歌会让你想起我》- 周华健 手机党少年们想听歌,请使劲儿戳(这里) ...

小小编辑
今天
112
4
Confluence 6 升级中的一些常见问题

升级的时候遇到了问题了吗? 如果你想尝试重新进行升级的话,你需要首先重新恢复老的备份。不要尝试再次对 Confluence 进行升级或者在升级失败后重新启动老的 Confluence。 在升级过程中的一...

honeymoose
今天
2
0
C++随笔(四)Nuget打包

首先把自己编译好的包全部准备到一个文件夹 像这样 接下来新建一个文本文档,后缀名叫.nuspec 填写内容 <?xml version="1.0"?><package xmlns="http://schemas.microsoft.com/packaging/201......

Pulsar-V
今天
3
0
再谈使用开源软件搭建数据分析平台

三年前,我写了这篇博客使用开源软件快速搭建数据分析平台, 当时收到了许多的反馈,有50个点赞和300+的收藏。到现在我还能收到一些关于dataplay2的问题。在过去的三年,开源社区和新技术的发...

naughty
今天
23
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部