想了幾天終於知道sql語句的發出問題查了很多書感覺都沒有說清楚有的還是錯的請看下面
[java]
<?xml version=?>
<!DOCTYPE hibernatemapping PUBLIC
//Hibernate/Hibernate Mapping DTD //EN
hiber/hibernatemappingdtd>
<hibernatemapping>
<class name=combjpowernodehibernateClasses table=t_classes>
<id name=id>
<generator class=native/>
</id>
<property name=name/>
<set name=students cascade=saveupdate>
<!
<key column=classesid notnull=true/>
>
<key column=classesid/>
<onetomany class=combjpowernodehibernateStudent/>
</set>
</class>
</hibernatemapping>
<?xml version=?>
<!DOCTYPE hibernatemapping PUBLIC
//Hibernate/Hibernate Mapping DTD //EN
hiber/hibernatemappingdtd>
<hibernatemapping>
<class name=combjpowernodehibernateClasses table=t_classes>
<id name=id>
<generator class=native/>
</id>
<property name=name/>
<set name=students cascade=saveupdate>
<!
<key column=classesid notnull=true/>
>
<key column=classesid/>
<onetomany class=combjpowernodehibernateStudent/>
</set>
</class>
</hibernatemapping>
[java]
<?xml version=?>
<!DOCTYPE hibernatemapping PUBLIC
//Hibernate/Hibernate Mapping DTD //EN
hiber/hibernatemappingdtd>
<hibernatemapping>
<class name=combjpowernodehibernateStudent table=t_student>
<id name=id>
<generator class=native/>
</id>
<property name=name/>
<manytoone name=classes column=classesid cascade=saveupdate/>
</class>
</hibernatemapping>
<?xml version=?>
<!DOCTYPE hibernatemapping PUBLIC
//Hibernate/Hibernate Mapping DTD //EN
hiber/hibernatemappingdtd>
<hibernatemapping>
<class name=combjpowernodehibernateStudent table=t_student>
<id name=id>
<generator class=native/>
</id>
<property name=name/>
<manytoone name=classes column=classesid cascade=saveupdate/>
</class>
</hibernatemapping>
測試的語句
[java]
session = HibernateUtilsgetSession();
sessionbeginTransaction();
Student student = new Student();
studentsetName(張三);
Classes classes = new Classes();
classessetName(動力節點);
studentsetClasses(classes);
//Set students = new HashSet();
//studentsadd(student);
classesgetStudents()add(student);
//拋出TransientObjectException
//因為Student不是Persistent狀態的對象它是Transient狀態的對象
sessionsave(classes);
session = HibernateUtilsgetSession();
sessionbeginTransaction();
Student student = new Student();
studentsetName(張三);
Classes classes = new Classes();
classessetName(動力節點);
studentsetClasses(classes);
//Set students = new HashSet();
//studentsadd(student);
classesgetStudents()add(student);
//拋出TransientObjectException
//因為Student不是Persistent狀態的對象它是Transient狀態的對象
sessionsave(classes);
Hibernate: insert into t_classes (name) values (?)
Hibernate: insert into t_student (name classesid) values (? ?)
Hibernate: update t_student set classesid=? where id=?
問題一既然是兩端維持關系為什麼不發出
Hibernate: insert into t_classes (name) values (?)
Hibernate: insert into t_student (name classesid) values (? ?)
而是發出三條語句呢?
答我猜想內部機制當它發現sessionsave(classes)時也就是保存一的一端的時候他會使用一的一端來維持關系這時候studentsetClasses(classes);這句話就不管了所以此時Hibernate: insert into t_student (name classesid) values (? ?)中的那個字段還是為空它看不到關系(孫衛琴老師的精通hibernate這本書這個地方說發出兩條sql語句是錯誤的)
當保存多的一端的時候他會使用多的一端來維持關系這時候classesgetStudents()add(student);這句話就不管了此時它能夠看到studentsetClasses(classes);所以保存Hibernate: insert into t_student (name classesid) values (? ?)中的那個字段不會為空它能夠看到關系
總結一句話保存一的一端會發出多條update的語句而保存多的一端不會發出多條update的語句(盡管是兩端維持關系但是會只用一端控制機制)
問題二級聯保存的時候是先保存多的一端還是先保存一的一端呢?
答不管是sessionsave(classes);還是sessionsave(students);一定是先保存一的一端再保存多的一端而不是先保存級聯的那個對象再保存save的這個對象(我以前一直是這樣理解的後來發現我錯了)
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28603.html