想了几天,终于知道sql语句的发出问题。查了很多书,感觉都没有说清楚,有的还是错的。请看下面:
[java]
< xml version="1.0" >
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
< xml version="1.0" >
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
[java]
< xml version="1.0" >
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
< xml version="1.0" >
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
测试的语句:
[java]
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);
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的这个对象(我以前一直是这样理解的,后来发现我错了)。