hibernate cascade

  • 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

转载于:https://my.oschina.net/u/2007041/blog/392619

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值