Hibernate - 多对多级联删除的问题

 

 

Hibernate多对多的例子不少,但仔细一看,大多数都是保存的,删除谈的少,但问题还不少,因此有必须简单测试一下,以下我们来个简单的多对多关系建立老师Teacher 课程Course 是一个多对多的关系,PojoXMl配置如下。

 

以下为 Pojo代码

=================================Course  Pojo================================

package com.domain;

import java.util.HashSet;

import java.util.Set;

 

/**

 * @author dengshaohua

 * @create_date 2011-09-14

 */

publicclass Course {

 

   private String id;

 

   private String name;

 

   private Set<Teacher> teachers = new HashSet<Teacher>();

 

   public String getId() {

      returnid;

   }

   publicvoid setId(String id) {

      this.id = id;

   }

   public String getName() {

      returnname;

   }

   publicvoid setName(String name) {

      this.name = name;

   }

   public Set<Teacher> getTeachers() {

      returnteachers;

   }

   publicvoid setTeachers(Set<Teacher> teachers) {

      this.teachers = teachers;

   }

}

================================Teacher  Pojo===============================

package com.domain;

import java.util.HashSet;

import java.util.Set;

 

/**

 * @author dengshaohua

 * @create_date 2011-09-14

 */ 

publicclass Teacher {

 

   private String id;

 

   private String name;

 

   private Set<Course> courses = new HashSet<Course>();

 

   public String getId() {

      returnid;

   }

   publicvoid setId(String id) {

      this.id = id;

   }

   public String getName() {

      returnname;

   }

   publicvoid setName(String name) {

      this.name = name;

   }

   public Set<Course> getCourses() {

      returncourses;

   }

   publicvoid setCourses(Set<Course> courses) {

      this.courses = courses;

   }

}

 

XML配置文件如下

=================================Course  XML================================

<?xml version="1.0"?> 

<!DOCTYPE hibernate-mapping PUBLIC  

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 

 

<hibernate-mapping> 

    <class name="com.domain.Course" table="tbl_course" 

       batch-size="100" dynamic-insert="true"

      dynamic-update="true">

        <id name="id" column="id"> 

            <generator class="uuid" /> 

        </id> 

        <property name="name" column="name" type="string" /> 

 

        <set access="property" lazy="true" inverse="false" 

           cascade="save-update" name="teachers"

         batch-size="10" fetch="select" 

           table="tbl_teacher_course"> 

           <key column="fk_course_id" /> 

           <many-to-many class="com.domain.Teacher" 

                column="fk_teacher_id" /> 

        </set>

      

    </class> 

</hibernate-mapping>

 

=================================Teacher  XML================================

<?xml version="1.0"?> 

<!DOCTYPE hibernate-mapping PUBLIC  

       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 

 

<hibernate-mapping> 

    <class name="com.domain.Teacher" table="tbl_teacher" 

       batch-size="100" dynamic-insert="true"

      dynamic-update="true"> 

        <id name="id" column="id"> 

            <generator class="uuid" /> 

        </id> 

        <property name="name" column="name" type="string" /> 

 

        <set access="property" lazy="true" inverse="true" 

            cascade="save-update" name="courses"

          batch-size="10" fetch="select" 

            table="tbl_teacher_course"> 

            <key column="fk_teacher_id" /> 

            <many-to-many class="com.domain.Course" 

                column="fk_course_id" /> 

        </set> 

    </class> 

</hibernate-mapping>

 

先往数据库里插入一些记录

publicvoid testSave() {  

     Session session = HibernateSessionFactory.getSession();  

     session.beginTransaction();  

 

     // create course  

     Course c1 = new Course();  

     Course c2 = new Course();  

     c1.setName("C");  

     c2.setName("Java");  

 

     // create teacher  

     Teacher t1 = new Teacher();  

     Teacher t2 = new Teacher();  

     t1.setName("Leo");  

     t2.setName("Rose");  

 

     // create relationship  

     c1.getTeachers().add(t1);  

     c1.getTeachers().add(t2);  

     t1.getCourses().add(c1);  

     t2.getCourses().add(c1);  

 

// 因为主控方级联设置为save-update,如果设置为none,则下面被注释的代码需要开启,否则会报错

     //session.save(t1);   

     //session.save(t2);  

     session.save(c1);  

     session.getTransaction().commit();  

     session.close();  

}

 

下面是测试的一些结果:

1. 如果cascade不管主控方设置还是被控方设置成 all, delete等与delete级联删除有关即可,两端以及中间表的记录都会被删除,通常这样的需要是很少的,因此,如果你要这样的情况,只要简单设置成all, delete就可以轻松的将关系以及两端的记录删除的干干净净。

2. 只想删除某一端的记录以及中间的表的关联信息。这种需求通常是很常见的。这个时候cascade的设置是除与delete有关的任何级联约束。

以下是删除心得:

如果删除的是主控方,只需要简单的删除这条记录,级联关系以及主控方的记录同时删除,但被控方的记录仍然存在。因此只对主控方的多对多删除是最简单,直接的。代码如下:

publicvoid testDelete() {  

    String id = "402881ee175f04be01175f04c05d0001";  

    Session session = HibernateSessionFactory.getSession();  

    session.beginTransaction();  

    Course c1 = (Course) session.get(Course.class, id);  

    session.delete(c1);  

    session.getTransaction().commit();  

    session.close();  

}

 

如果你这个时候想直接删除被控方,那么很遗憾的告诉你,你只做到了一半,你只是简单的把被控方的记录删除了,关联关系仍然存在中间表里,系统随时会因为你的关联访问报错,代码如下:

publicvoid testDeleteByInverse() {  

    String id = "402881ee175a2e7c01175a2e7ead0003";  

    Session session = HibernateSessionFactory.getSession();  

    session.beginTransaction();  

    Teacher t1 = (Teacher) session.get(Teacher.class, id);  

    session.delete(t1);  

    session.getTransaction().commit();  

    session.close();  

}

 

如果想既想删除被控方,双想删除关联,请看下面代码:

publicvoid testDeleteByInverse2() {  

    String id = "402881ee175f04be01175f04c06c0002";  

    Session session = HibernateSessionFactory.getSession();  

    session.beginTransaction();  

    Teacher t1 = (Teacher) session.get(Teacher.class, id);  

    Set<Course> cs = t1.getCourses();  

    for (Course c : cs) {  

        c.getTeachers().remove(t1);  

    }  

    session.delete(t1);  

    session.getTransaction().commit();  

    session.close();  

}

你可能感兴趣的:(Hibernate)