多对多的映射:多个老师对应多个学生
由于此类操作较为繁琐,且浪费资源,较多的是将其更改为一对多的映射,即增加中间层,设计成多对多映射.
 
teacher.hbm.xml
<class name="Teacher">
    <id name="id">
      <generator class="native" />
    </id>

    <property name="name" unique="true" />
    <set name="students" table="teacher_student">
      <!-- 告诉Hibernate,集合中存放的是student,同时声明中间表的名称 -->
      <key column="teacher_id"></key>
      <many-to-many class="Student" column="student_id" />
    </set>
  </class>
 
student.hbm.xml
<class name="Student">
    <id name="id">
      <generator class="native" />
    </id>

    <property name="name" unique="true" />
    <set name="teacher" table="teacher_student">
      <key column="student_id" />
      <many-to-many class="Teacher" column="teacher_id"/>
    </set>
  </class>
 
测试代码:
Set<Teacher> ts = new HashSet<Teacher>();
      Teacher t1 = new Teacher();
      t1.setName("t1 name");

      Teacher t2 = new Teacher();
      t2.setName("t2 name");

      ts.add(t1);
      ts.add(t2);
        
      Set<Student> ss = new HashSet<Student>();
      Student s1 = new Student();
      s1.setName("s1 name");

      Student s2 = new Student();
      s2.setName("s2 name");
      ss.add(s1);
      ss.add(s2);
        
      // 告诉学生他们的老师
      s1.setTeacher(ts);
      s2.setTeacher(ts);
        
      // 告诉老师他们的学生
//      t2.setStudents(ss);

      s = HibernateUtils.getSession();
      tx = s.beginTransaction();

      s.save(t1);
      s.save(t2);
      s.save(s1);
      s.save(s2);

      tx.commit();
 
这里,特别的要留意,如果告诉学生他们的老师后,老师也就知道了他们的学生,如果这时候再告诉老师他们的学生,则会抛出主键冲突的异常.
原因是这样:
由于告诉学生他们的老师时,Hibernate更新了中间表:teacher_student,而teacher_student是由teacher_id和student_id联合组成的联合主键,此时该主键由学生维护.