Session.save正在更新hibernate中的数据

Session.save正在更新hibernate中的数据,hibernate,Hibernate,我正在尝试在hibernate会话中保存学生信息的示例代码。save()。其中包括学生姓名、班级、教师id 表:学生 SNO SNAME SCLASS TNO ----------- ---------------------------------------- 1 J D Alex 3 1 2 Goaty 2 2 3 J D Paul

我正在尝试在hibernate会话中保存学生信息的示例代码。save()。其中包括学生姓名、班级、教师id

表:学生

SNO SNAME             SCLASS         TNO
----------- ----------------------------------------
1 J D Alex            3                1
2 Goaty               2                2
3 J D Paul            7                1
代码:-

Transaction tx1=session1.beginTransaction();
Object o2=session1.get(Student.class,new Integer(3));
((Student)o2).setSclass("8");
session1.save(o2);
log.info("loadStdYearlyInfo:class "+((Student)o2).getSclass());
tx1.commit();
session1.close();
保存数据并查看输出后,对于学生id为3,类值更新为8

 SNO SNAME             SCLASS         TNO
    ----------- ----------------------------------------
    1 J D Alex            3                1
    2 Goaty               2                2
    3 J D Paul            8                1

[07/May/2012:10:03:06] info ( 3500): CORE3282: stdout: Hibernate: /* load com.aims.beans.Student */ select student0_.sno as sno0_, student0_.sname as sname1_0_, student0_.sclass as sclass1_0_, student0_.tno as tno1_0_ from student student0_ where student0_.sno=?
[07/May/2012:10:03:06] info ( 3500): CORE3282: stdout: loadStdYearlyInfo:class 8
[07/May/2012:10:03:06] info ( 3500): CORE3282: stdout: Hibernate: /* update com.aims.beans.Student */ update student set sname=?, sclass=?, tno=? where sno=?
[07/May/2012:10:03:06] info ( 3500): CORE3282: stdout: loadStdYearlyInfo2

如何更新数据库中的学生类值?保存意味着插入数据。但此处的值已更新。如果有问题,请告诉我。如果有问题,请回答。对不起。

我认为这是因为您正在处理事务。当您提交事务时,它会自动刷新对已加载实体的任何更改,在本例中为您的学生对象。
它不会保存对象,因为它已将唯一标识符附加到会话。
我原以为Hibernate会抛出异常,因为您试图保存已连接的对象


我希望这对你有所帮助。

这是一种预期的行为


get
返回的对象是持久的。基本上,对持久对象的
save
调用被忽略。但是Hibernate会自动跟踪持久对象中的更改并相应地更新数据库,因此会出现
update
语句。

这是Hibernate的预期行为

当hibernate会话加载记录时,其实例将处于状态并由该会话管理。如果永久实例的值发生更改,则它们将被视为脏实例。在刷新过程中(即,
Session.flush()
),hibernate将查找所有脏实例(我们称此过程为
自动脏检查
)并生成并发出必要的SQL,以更新相应的DB记录,以确保DB记录与JVM中保存的相应实例具有相同的状态

休眠会话的刷新行为由
FlushMode
确定。默认情况下,它是
FlushMode.AUTO
,这意味着在提交事务或执行查询之前将自动调用
session.flush()
。因此,在代码中,虽然没有显式调用
session.flush()
,但刷新过程仍然会发出这些更新语句

关于守则的一些评论:

Transaction tx1=session1.beginTransaction();   

/**
 * o2 is the in the persistent state and managed by session1
 */
Object o2=session1.get(Student.class,new Integer(3));

/**
 *As the value of o2 is changed , it becomes dirty and hibernate will issue an UPDATE SQL 
 *for it during flushing.
 */
 ((Student)o2).setSclass("8");

/**
 * save() only has effect on the transient instance. Nothing will 
 * be done when calling it on the persistent instance . So removing this line of code 
 * still produces the same result.
 */
session1.save(o2);
log.info("loadStdYearlyInfo:class "+((Student)o2).getSclass());

/**
 *I believe default FlushMode (FlushMode.AUTO) is used in here ,so session.flush()  will be invoked implicitly before tx1.commit().
 *Automatic dirty checking occurs and UPDATE SQL is generated and issued to the DB 
 *to update the dirty o2 instance
 */ 
tx1.commit();
session1.close();

非常透彻的解释。教了我一些东西什么是自动脏检查?Hibernate自动跟踪持久对象的状态更改,并在刷新期间更新脏对象。这只是一个描述这种能力的术语。设置session1.FetchMode(FetchMode.Manual)之后,它就避免了更新值。thanks@KenChan-由于save也将通过自动脏检进行更新,所以我们不需要saveOrUpdate,对吗??或者有任何情况下,saveOrUpdate比save更可取,因为save也会通过自动脏检进行更新,所以我们不需要saveOrUpdate,对吗??或者存在saveOrUpdate优先于save的情况