`
juforg
  • 浏览: 44753 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

(转)Hibernate映射多对一单向关联(之二)

阅读更多
前提:在 Hibernate映射多对一单向关联(之一) 中配置的映射文件的基础上。
看一下级联更新,其实和插入是一致的。但是这里面有几点需要特别注意。
student表和teacher表都有一个自增长的id。
student表中的一条记录为id=20,sno=200802,sname=Shirdrn;
teacher表中的一条记录为id=1,tname=王老师。
执行级联更新的测试程序这样写:
package org.shirdrn.test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.shirdrn.HibernateSessionFactory;
import org.shirdrn.entity.Student;
import org.shirdrn.entity.Teacher;
public class MyTest {
public static void main(String[] args){
   Session session = HibernateSessionFactory.getSession();
   Transaction tx = null;
   try{
    tx = session.beginTransaction();
    Student stu = new Student();
    stu.setId(new Integer(20));
    stu.setSno("2008002");
    stu.setSname("关羽");
    Teacher t = new Teacher();
    t.setId(new Integer(1));
    t.setTname("张老师");
    stu.setTeacher(t);
    session.update(stu);
    tx.commit();
   }
   catch(Exception e){
    tx.rollback();
    e.printStackTrace();
   }
   finally{
    HibernateSessionFactory.closeSession();
   }
}
}
执行结果,控制台提示:
Hibernate: update student set sno=?, sname=?, dept=? where id=?
Hibernate: update hibernate.dbo.teacher set tname=? where id=?
可见级联更新成功。
但是,如果我们只是指定了Student的id,但是忘记了指定Teacher的id,即上面程序中没有t.setId(new Integer(1));的设置,则显然可以想到会是怎样的结果:
Hibernate: insert into hibernate.dbo.teacher (tname) values (?) select scope_identity()
Hibernate: update student set sno=?, sname=?, dept=? where id=?
student表当然执行的是更新操作,而teacher表没有指定id,则执行过程中认为对teacher表的操作是insert操作,故而得到一个插入一个更新的结果。

看一下删除操作:
只有这样才可以成功删除学生的记录。package org.shirdrn.test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.shirdrn.HibernateSessionFactory;
import org.shirdrn.entity.Student;
import org.shirdrn.entity.Teacher;
public class MyTest {
public static void main(String[] args){
   Session session = HibernateSessionFactory.getSession();
   Transaction tx = null;
   try{
    tx = session.beginTransaction();
    Student stu = new Student();
    stu.setId(new Integer(19));
    stu.setSno("2008001");
    stu.setSname("shirdrn");
    session.delete(stu);
    tx.commit();
   }
   catch(Exception e){
    tx.rollback();
    e.printStackTrace();
   }
   finally{
    HibernateSessionFactory.closeSession();
   }
}
}
在控制台上看到执行结果:
Hibernate: delete from student where id=?
我建的那个表id是自增长的,而且sno和sname都不能为空,所以删除必须把这些字段都指定,否则就会报异常:
org.hibernate.PropertyValueException: not-null property references a null or transient value: org.shirdrn.entity.Student.sname
at org.hibernate.engine.Nullability.checkNullability(Nullability.java:72)
at org.hibernate.event.def.DefaultDeleteEventListener.deleteEntity(DefaultDeleteEventListener.java:205)
at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:109)
at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:579)
at org.shirdrn.test.MyTest.main(MyTest.java:23)
因为这和我的表的设置有关。试想,id为主键,不同,所以学生的记录(包括sno,sname)可以相同。

看一下级联删除操作:
程序如下:
package org.shirdrn.test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.shirdrn.HibernateSessionFactory;
import org.shirdrn.entity.Student;
import org.shirdrn.entity.Teacher;
public class MyTest {
public static void main(String[] args){
   Session session = HibernateSessionFactory.getSession();
   Transaction tx = null;
   try{
    tx = session.beginTransaction();
    Student stu = new Student();
    stu.setId(new Integer(27));
    stu.setSno("2008007");
    stu.setSname("关小羽");
    Teacher t = new Teacher();
    t.setId(new Integer(4));
    t.setTname("王老师");
    stu.setTeacher(t);
    session.delete(stu);
    tx.commit();
   }
   catch(Exception e){
    tx.rollback();
    e.printStackTrace();
   }
   finally{
    HibernateSessionFactory.closeSession();
   }
}
}
如果在上面配置文件的前提下执行删除操作,则会只是删除指定的学生的记录,控制台结果如下所示:
Hibernate: delete from student where id=?
如果想要能够实现级联操作,可以修改Student.hbm.xml中的配置,只需要把cascade="save-update"改成:
cascade="all"
这时,不仅可以级联存储更新,删除也可以级联实现,控制台上打印出来:
Hibernate: delete from student where id=?
Hibernate: delete from hibernate.dbo.teacher where id=?
如果,在SQL Server 2000中没有指定表student和teacher表之间的约束的前提下,insert、update、delete操作都可以对两个表单独进行操作。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics