<?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.bjpowernode.hibernate.Classes" table="t_classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="students" cascade="save-update">
<!--
<key column="classesid" not-null="true"/>
-->
<key column="classesid"/>
<one-to-many class="com.bjpowernode.hibernate.Student"/>
</set>
</class>
</hibernate-mapping>


 

<?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.bjpowernode.hibernate.Student" table="t_student">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="classes" column="classesid" cascade="save-update"/>
</class>
</hibernate-mapping>


测试的语句:

session = HibernateUtils.getSession();
session.beginTransaction();

Student student1 = new Student();
student1.setName("张三");

Classes classes = new Classes();
classes.setName("动力节点");

student1.setClasses(classes);

//Set students = new HashSet();
//students.add(student1);
classes.getStudents().add(student1);

//抛出TransientObjectException
//因为Student不是Persistent状态的对象,它是Transient状态的对象
session.save(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 (?, ?)

而是发出三条语句呢?

答:我猜想内部机制,当它发现session.save(classes)时,也就是保存一的一端的时候,他会使用一的一端来维持关系,这时候student1.setClasses(classes);这句话就不管了。所以此时Hibernate: insert into t_student (name, classesid) values (?, ?)中的那个字段还是为空。它看不到关系。(孙卫琴老师的精通hibernate这本书这个地方说发出两条sql语句是错误的)

当保存多的一端的时候,他会使用多的一端来维持关系,这时候classes.getStudents().add(student1);这句话就不管了。此时它能够看到student1.setClasses(classes);所以保存Hibernate: insert into t_student (name, classesid) values (?, ?)中的那个字段不会为空。它能够看到关系。

总结一句话:保存一的一端会发出多条update的语句。而保存多的一端不会发出多条update的语句(尽管是两端维持关系,但是会只用一端控制机制)。

 

问题二:级联保存的时候,是先保存多的一端还是先保存一的一端呢?

答:不管是session.save(classes);还是session.save(students);一定是先保存一的一端,再保存多的一端。而不是先保存级联的那个对象,再保存save的这个对象(我以前一直是这样理解的,后来发现我错了)。