想了几天终于知道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的这个对象(我以前一直是这样理解的后来发现我错了)