public void testMerge()
{
Teacher t = new Teacher();
t.setId(4);
t.setName("力量1");
t.setStudentNum("100");
//t为detached态
session = sf.openSession();
session.beginTransaction();
//System.out.println("id"+t.getId());
/*Teacher t = session.get(Teacher.class,1);
session.clear();
t2.setName("liliang");
session.update(t2);*/
//System.out.println("id"+t.getId());
//session.get
//System.out.println(t.getClass());
session.getTransaction().commit();
session.close();
//System.out.println("id"+t.getName());
sf.close();
{
Teacher t = new Teacher();
t.setId(4);
t.setName("力量1");
t.setStudentNum("100");
//t为detached态
session = sf.openSession();
session.beginTransaction();
Teacher t2 = session.get(Teacher.class,4);
session.update(t);//
session.merge(t);////System.out.println("id"+t.getId());
/*Teacher t = session.get(Teacher.class,1);
session.clear();
t2.setName("liliang");
session.update(t2);*/
//System.out.println("id"+t.getId());
//session.get
//System.out.println(t.getClass());
session.getTransaction().commit();
session.close();
//System.out.println("id"+t.getName());
sf.close();
}
当使用update,因为有一个id为4的persistent态实例,会报错
使用merge时,能成功执行
首先,对于一个处于detatch状态的实体对象来说,要将其中的修改,合并到数据库中,有两种方法,一种方式,是调用update(),另一种方式是调用merge()
当调用update()时,首先要取保目标session中,不包含同样id的实体对象的引用,如果有的话,会抛出异常,完成update()方法后,这个实体对象从detatch状态,转换为persistent状态,在session提交前,后续对其的修改,都会被合并到数据库中。
当调用merge()对象时,无需考虑session中是否已经包含同样id的实体对象,如果session中没有同样id的实体对象,hibernate会通过select语句,从数据库中查询出对应对象,如果数据库中没有对应对象,就新建一个。同时,完成merge()操作后,会返回数据库中对应的persistent状态对象,而原有的,作为参数传入的实体对象,仍然是detatch状态,后续代码对其的修改,无法合并到数据库中。