1. 程式人生 > >在一對多關係中為什麼要讓多的一端維護關聯關係

在一對多關係中為什麼要讓多的一端維護關聯關係

有兩個類,Class表示班級,Student表示學生,兩者之間是一對多的關係。

Class有以下屬性:

private int id;//id號
 private String name;//班級名
 private Set students;//學生集合

Student有以下屬性:

private int id;//id號
 private String name;//姓名
 private Class cla;//班級

Class.hbm.xml配置如下:

 <hibernate-mapping>
 <class table="t_class" name="cn.edu.cqu.model.Class">
  <id name="id">
   <generator class="native"/>
  </id>
  <property name="name"/>
  <set name="students" cascade="all">


   <key column="cid"/>
   <one-to-many class="cn.edu.cqu.model.Student"/>
  </set>
</class>
</hibernate-mapping>

Student.hbm.xml配置如下:

<hibernate-mapping>
 <class table="t_student" name="cn.edu.cqu.model.Student">
  <id name="id">
   <generator class="native"/>
  </id>
  <property name="name"/>
  <many-to-one name="cla" column="cid"/>
 </class>
</hibernate-mapping>

這時候,在Class的對映檔案中的一對多標籤中沒有配置inverse屬性,表示這個一對多關係由Class主控,這時,如果通過Class儲存Student(在一對多標籤中配置了cascade="all",儲存Class的時候會將與之關聯的Student也儲存到資料庫中),比如:

 session.beginTransaction();
   cn.edu.cqu.model.Class c1=new cn.edu.cqu.model.Class();
   c1.setName("軟體班");
   Set students=new HashSet();
   c1.setStudents(students);
   
   Student s1=new Student();
   s1.setName("Tom");
   
   c1.getStudents().add(s1);


   session.save(c1);
   session.getTransaction().commit();

Hibernate在儲存Student的時候會執行兩條sql語句:

Hibernate: insert into t_class (name) values (?)

Hibernate: insert into t_student (name, cid) values (?, ?)
Hibernate: update t_student set cid=? where id=?

第一條語句將Student儲存到資料庫中,cid為空,第二條語句由Class物件將剛才存入資料庫中的Student的id號設為自己的id號

如果將Student的cla屬性配置為not-null="true",即表t_student的cid欄位為not null就會出現異常:

not-null property references a null or transient value: cn.edu.cqu.model.Student.cla

所以,在配置一對多關係的時候,最好將關聯控制交給多的一端維護。