【http://blog.sina.com.cn/s/blog_625d79410101dbdd.html】

  看过前两篇帮助文档 【JPA】 @OneToOne 单向 和 【JPA】@OneToOne 双向 想必大家对级联操作已经充满了好奇和期待吧。那么本文将会想大家介绍JPA的级联保存操作。在此之前,我希望你能先看下这篇文档,对级联注释的各个属性有一个大概的了解。传送门:【JPA】 级联标签的解释 @Cascade
      在生活中,有许多关系都是一对多的。School(学校)和 Studnet(学生) 之间的关系就是典型的一对多关系。一所学校,有多名学生。但是一个学生,只能属于一所学校。在这里,我们将这个关系设置为一个双向的关系。也就说,通过学生实体,我们可以得到他就读的学校的实体。同样,通过一个学校实体,我们也可一得到在这所学校就读的学生实体的集合。
 
--------< 例 子 >----------------------------------------------------------------------------------------------------------
 
//学生Model , 这个双向一对多关系的维护端。一般来说,在双向一对多关系中,"多"这一端,一般都是关系的维护端。
@Entity
@Table(name = "student")
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
 
    //在表中建立外键 "school_fk"
    
    @ManyToOne
    @JoinColumn(name="school_fk")
    private School school;
   
//省略若干get / set
}
 
 
@Entity
@Table(name = "school")
public class School {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
 
    @OneToMany(mappedBy="shcool")
    //设置 :级联 保存/新建 操作 。新建 学校和学生 的时候,保存新建的学校那么新建的学生也同时被保存
    @Column(cascade={CascadeType.PERSIST})
    private List students;
 
    //手动构造添加学生的方法
    public void addStudent(Strudent stu){
            if(stu != null){
                 students.add(stu);
            }
    }
 
//省略若干get / set
}
-----------------------------------------------------< 测试方法 >--------------------------------------------------------------
public class Test(){
 
    public void testCreate(){
         School school = new School();
         school.setName("学校");
 
         Student st1 = new Student();
         st1.setName("学弟");
         st1.setSchool(school);
         studnetDAO.save(st1);
       
         Student st2 = new Student();
         st2.setName("学长");
         st2.setSchool(school);
         studnetDAO.save(st2);
 
         //添加学生
         school.addStudent(st1);
         school.addStudent(st2);
         schoolDAO.save(school);
        //以上的保存方法并不是级联保存操作。我们在学校实体上设置了,级联保存操作。
        //我们希望JPA这样做,在新建学校,新建多名学生时。只要将学生的所属学校设置完成后,保存学校,即可保存 所属该校的学生。
    }
 
    //级联保存,测试方法
    public void testPersistCreateSchool(){
            //级联保存演示:已经在学校(School)Model 中添加了 级联保存操作:cascade={CascadeType.PERSIST}
       
         School school = new School();
         school.setName("学校");
 
         Student st1 = new Student();
         st1.setName("学弟");
         st1.setSchool(school);
         //  不需要显示保存学生 st1
         //studnetDAO.save(st1); 
       
         Student st2 = new Student();
         st2.setName("学长");
         st2.setSchool(school);
         //  不需要显示保存学生 st2
         //studnetDAO.save(st2);
 
         //添加学生
         school.addStudent(st1);
         school.addStudent(st2);
         schoolDAO.save(school);// 保存学校,学校内新建的学生也[st1、st2]被保存了。(级联保存)
    }
 
    //测试删除
    public void testDeleteSchool(){
            //革命第一步,创建学校。
            testCreate();
            schoolDAO.delete(school);//后台报错
            //avax.persistence.RollbackException: Error while commiting the transaction Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint...
              
             //之前我们已经知道,想要删除关系的被维护端,必须先从维护端解除关系。才能正常删除。所以我们要做的就是,先从 学生端,解除关系。
    
        List<Strudnet> students = school.getStudentList();
        for(int i=0;i<students.size();i++){
                Student stu = students.get(i);
                stu.setSchool(null);//手动从学生实体解除挂系
        }
        schoolDAO.delete(school);//现在,学校被正常的删除了。该校的两名学生信息依然保存在数据库中。只是,他们没有所属学校了。
 
        //看到这里,你一定会责备我。JPA不是很强大么?不是很灵活多变么?不是很神奇么?
        //为什么删除一个实体,还需要循环解除关系,这么繁琐的操作?!
        //其实,我们有方法可以直接删除学校。并且,不需要进行这种循环从学生实体解除关系的操作。但是,相信我,这种方法你可能不会接受。下面,就让我们来看看JPA的级联删除。
        //修改学校的Model 中,在校生字段()的注释:@Column(cascade={CascadeType.PERSIST})
        //改为:@Column(cascade={CascadeType.PERSIST,CascadeType.REMOVE}) 添加级联删除操作。那么,现在你就可以直接调用删除学校的方法了。
        schoolDAO.delete(school);//现在,学校也被正常删除了。但是,接下来的一幕,你可能不愿意看到。
        Stduent stu = studentDAO.findByName(学长");
        //打印的结果为: null   是的,你没看错。该校所有的学生也被级联删除了...
        //此时,你应该对JPA的级联删除有所理解了。它删除的对象是实体。级联指的是级联实体。如果,在学生的Model 中添加了一个级联删除的操作,那么删除一个学生,那这个学生所属的学校也会被删除掉。
        //所以,在这里,我要提醒你。级联的删除操作要慎用。因为,他的破坏性太大了。级联删除的操作,并不是针对某个字段,而是它所管理的实体。
}
       
        //测试删除
        public void testDeleteStudent(){
        //创建学校和学生
        testCreate();
        studentDAO.delete(st1);//此时,st1(创建时,名字叫“学弟”的学生)已经被从数据库中删除了。但是,他所属的学校并没受影响。只不过,st1已经从 学校的 学生集合里删除了。这都是由JPA来完成的。
 
        //现在,我们假设:我们没有执行刚才那部。st1没有被删除。学校依然拥有两名学生。
        //在,Stuent的Model 中添加级联删除的操作。@JoinColumn(name="school_fk",cascade={CascadeType.REMOVE})   并且,School 的 Model中也添加级联删除的操作。
        //此时,数据库中,只有一所学校和两名学生的信息。
        studentDAO.delete(st1);
        //哇,全世界都干净了。如果这个时候查看数据库。你会发现,所有的数据都没了。为什么会这样呢?
        //让我们来看看JPA都干了什么:
        1:删除 st1
        2:school 被 st1 级联删除
        3:st2 被 school 级联删除
        //所以,你才会发现,数据库中所有的信息都消失了。当然,如果之前,数据库中还有别的学校和别的学校所属学生。那么它们的信息是不受影响的。
       //罗嗦了这么多,我感到很抱歉。我只是想提醒你,一定要慎用这个级联的删除操作。千万不用在建立Model 的时候,顺手添加一个级联保存 删除之类的操作。一定要根据自己的需求。和操作的实际效果,仔细斟酌之后,再付诸于行动。否则,你直接来个CascadeType.ALL 大多数情况下,它带给你的都是痛苦的回忆。
 
       }
//省略main 方法
}

【JPA 级联保存/级联删除】@OneToMany (双向) 一对多【转】的更多相关文章

  1. hibernate 一对多 级联 保存修改 删除

    一对多,一端设置: <set name="TWorkorderHistories" inverse="true" cascade="all&qu ...

  2. Hibernate的级联保存、级联删除

    级联操作: 属性:cascade 值:save-update(级联保存) delete(级联删除) all(级联保存+级联删除) 优点:虽然,不用级联操作也能解决问题.但是级联操作可以减少代码量,使得 ...

  3. (原创)Hibernate 使用过程中(尤其是多对多关联中的级联保存和级联删除)的注意事项(基于项目的总结)

    一.先上知识点: 1.hibernate多对多关联关系中最重要的参数是(基于配置文件xxx.hbm.xml文件形式): 1):inverse属性,如果设置inverse=“true”就代表让对方参与维 ...

  4. Hibernate中表与表之间的关联一对多,级联保存和级联删除

    1:Hibernate的一对多操作(重点) 一对多映射配置 第一步:创建两个实体类:客户和联系人(例)以客户为一,联系人为多: package com.yinfu.entity; public cla ...

  5. Hibernate中表与表之间的关联多对多,级联保存,级联删除

    第一步:创建两个实体类:用户和角色实体类,多对多关系,并让两个实体类之间互相关联: 用户实体类: package com.yinfu.entity; import java.util.HashSet; ...

  6. Hibernate入门(八)级联保存或更新(含问题在末尾,求大佬指点..)

    级联保存或更新CASCADE 级联保存或更新: 作用就是:保存一方的数据的时候,会把关联的对象也同时保存. 级联保存或更新的配置: 属性名:cascade 属性值: 1.none:所有情况下均不进行关 ...

  7. 测试开发专题:spring-boot如何使用JPA进行双向一对多配置

    本片文章我们主要介绍spring-boot如何进行JPA的配置以及如何进行实体间的一对多配置. 依赖准备 要在spring-boot使用jpa需要在项目中有进入相关的依赖,pom文件里加入下面内容 & ...

  8. JPA学习笔记(8)——映射双向一对多关联关系

    双向一对多关联关系 前面的博客讲的都是单向的,而本问讲的是双向的(双向一对多 = 双向多对一) 什么是双向? 我们来对照一下单向和双向 单向/双向 User实体类中是否有List< Order& ...

  9. SQL图形化操作设置级联更新和删除

    SQL级联操作设置   对SQL数据库的表,进行级联操作(如级联更新及删除),首先需要设置表的主外键关系,有两种方法:   第一种:   1. 选择你要进行操作的数据库   2. 为你要创建关系的两个 ...

随机推荐

  1. htop 比top更好用的top

    安装 sudo apt-get install htop 使用 htop

  2. 关于hugepages 3.txt

    关于hugepages 3.txt --//有一段时间我一直强调安装oracle一定要配置hugepage,因为现在的服务器内存越来越大,如果还使用4K的页面表,如果内存表占用内存巨大, --//特别 ...

  3. jq对页面元素进行排序

    利用sort函数排序: var div = $('.media').toArray().sort(function(a,b){ return parseInt($(a).find('.info .pr ...

  4. 图片服务器(FastDFS)的搭建

    1.1 什么是FastDFS FastDFS是用c语言编写的一款开源的分布式文件系统.FastDFS为互联网量身定制,充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高性能等指标,使用Fa ...

  5. Caesars Cipher

    让上帝的归上帝,凯撒的归凯撒. 下面我们来介绍风靡全球的凯撒密码Caesar cipher,又叫移位密码. 移位密码也就是密码中的字母会按照指定的数量来做移位. 一个常见的案例就是ROT13密码,字母 ...

  6. 从HDC转换到leptonica PIX

    void CAssistDlg::OnBnClickedTest() { HDC hdc = ::GetDC(NULL); HDC hdcMem = CreateCompatibleDC(hdc); ...

  7. linux oracle11g 数据 导入到10g数据库

    说明: 原用户名和密码:test/test  目标用户名和密码:test01/test 11G 服务器: 1.创建dmp文件存储目录 # mkdir -p /tmp/backup # sqlplus ...

  8. C#学习历程(五)[高阶概念]

    >>修饰符的访问权限 private : 私有成员, 在类的内部才可以访问. protected: 保护成员,该类内部和继承类中可以访问. public: 公共成员,完全公开,没有访问限制 ...

  9. SpringAnnotation之配置AnnotationXML文件

    配置Annotation的环境:只需修改applicationContext.xml文件即可 1 2 3 4 5 6 7 8 9 10 11 <?xml version="1.0&qu ...

  10. DS导入导出命令详解

    1.导出例子如下:$DSHOME/../../Clients/istools/cli/istool export -dom dpapp01 -u edpusr -p edpusr -ar /home/ ...