zoukankan      html  css  js  c++  java
  • 谈论Hibernate级联删除——JPA根据Hibernate实现许多级联删除CascadeType.DELETE_ORPHAN

    声明:
    1、这篇文章是原创。非复制或转载过来。
    2、在本文中,参数都亲自做过实验证明。
    3、这篇文章谈到了Hibernate配置基于注释的方法。hbm语法不可用。
    不清JPA、Hibernate、EJB3.0的关系,这里做一下简单的说明:JPA是一个持久层设计接口。EJB3.0和Hibernate是详细的实现类。EJB3.0和Hibernate的功能近似相等的(Hibernate没有Session Bean,Spring MVC3的SessionAttribute跟Session Bean近似)。
    理论是使用JPA接口能够无缝切换持久层实现,可是不过理论上!

    !!




    JPA是在Hibernate成熟并大行其道的时候才推出的,基本上是借鉴Hibernate的长处。做了一个统一的标准而已,JPA1.0没有一对多的级联删除配置。或许JPA2.0里才有吧(这里没做过调研)
    @OneToMany(mappedBy = "commentTeam")
    @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
    private Set<CommentTeamMember> commentTeamMembers;
    这里为了说明,仅仅贴出一对多的关键代码。其他无关的注解已忽略掉,以免造成干扰。


    这里重点说明一下四个经常使用的注解配置的差别:
    CascadeType.SAVE_UPDATE
    CascadeType.ALL
    CascadeType.DELETE
    CascadeType.DELETE_ORPHAN


     之全部之列出这四个,是由于我不想跟书本上把全部的概念都罗列出来。基本上开发时当中的3个都以及足够用了,以下我结合代码演示一下他们之间的差别,以及使用的时候注意的地方。
    CascadeType.SAVE_UPDATE:Hibernate专有的。JPA并不支持。作用是级联保存、级联更新(注:JPA非常恶心,要么你配置
    CascadeType.ALL,要么你配CascadeType.SAVE+CasadeType.Merge。八卦一句:专家虽牛。多年不写代码。定的标准让编码麻烦呀!)
    CascadeType.ALL:级联保存、改动、删除、同步。一般非常少用,看看控制台的一长串SQL就知道性能低下。你没改的关联表也给你发update语句。我从来没用过这个属性。
    CascadeType.DELETE:当调用session.delete(A)的时候,级联删除关联的对象。(注:先调用A.setB(null),再调用session.delete(A),这样是级联删不掉B的。


    CascadeType.DELETE_ORPHAN:一对多级联删除。


    以下重点来说说这个CascadeType.DELETE_ORPHAN:
    看过API、开发指南。级联删除就一个经典的
    @OneToMany(mappedBy = "commentTeam")
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.DELETE_ORPHAN})
    private Set<CommentTeamMember> commentTeamMembers;


    mappedBy不可少,映射A->B一对多的还有一边控制反转(谁控谁的问题),新版的Hibernate3.4中配置更简单。变一句了,更简洁吧?
    @OneToMany(mappedBy = "commentTeam",orphanRemoval=true) 
    private Set<CommentTeamMember> commentTeamMembers;


    以上两种配置方式是等价的,以下是在实际开发中的使用了,有些时候代码方面不注意,会误以为明明配置正确了。但为什么不起作用呢? 以下例举一下代码,请看Action代码(实际上我在Spring Controller里。N年不写DAO了,Service非常少用,Manager一边去!


    CommentTeam commentTeam=this.getHibernateTemplate.get(CommentTeam.class,id);
    commentTeam.setCommentTeamMember(null);//想级联删除子表数据
    this.getHibernateTemplate.saveOrUpdate(commentTeam);
    这样级联删除却没有发生?为什么呢?
    再来一个样例
    CommentTeam commentTeam=this.getHibernateTemplate.get(CommentTeam.class,id);
    Set<CommentTeamMember> commentTeamMembers=new HashSet<CommentTeamMember>();
    commentTeam.setCommentTeamMember(commentTeamMembers);//想级联删除子表数据或增减替换对象
    this.getHibernateTemplate.saveOrUpdate(commentTeam);
    这个样例级联删除的效果也没发生!即使commentTeamMembers理由有若干个对象。


    成功运行级联删除的语法:
    CommentTeam commentTeam=this.getHibernateTemplate.get(CommentTeam.class,id);
    commentTeam.getCommentTeamMember().clear();//注意这里引用的集合还是原理的集合,这里没有又一次new过
    commentTeam.getCommentTeamMember().add(new CommentTeamMember());//假设想替换为新的集合能够用addAll方法
    this.getHibernateTemplate.saveOrUpdate(commentTeam);

    分析一下原因:级联删除起作用的前提是关联的集合对象不能又一次指向新的引用,必须在原有的集合里操作新增、删除、清空元素,像上面的setXXX(null)的方法等是起步到级联删除作用的,大概是Hibernate自认自己原生的集合对象吧。自己New的放进行级联删除无效!



    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
  • 相关阅读:
    [TensorFlow]TensorFlow安装方法
    [Linux]CentOS与终端破墙
    [JavaScript,Java,C#,C++,Ruby,Perl,PHP,Python][转]流式接口(Fluent interface)
    ROS中阶笔记(十一):ROS 2.0
    ROS中阶笔记(十):ROS机器人综合应用
    ROS中阶笔记(九):Movelt!机械臂控制
    ROS中阶笔记(八):机器人SLAM与自主导航—机器人自主导航
    ROS中阶笔记(七):机器人SLAM与自主导航—SLAM功能包的使用
    ROS中阶笔记(六):机器人感知—机器语音
    ROS中阶笔记(五):机器人感知—机器视觉
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4590712.html
Copyright © 2011-2022 走看看