我试图在hibernate session.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();
保存数据并看到输出后,类值更新为8,学生ID为3
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
如何更新数据库中的学生班级值?.save意味着插入数据。但是这里的值已更新。请告诉我。如有任何问题?。如果有任何错误,那么抱歉。
答案 0 :(得分:7)
这是Hibernate的预期行为。
当hibernate会话加载记录时,其实例将处于persistent状态并由此会话管理。如果更改持久性实例的值,则将它们视为脏。在刷新过程中(即Session.flush()
),hibernate将找出所有脏实例(我们称之为此进程automatic dirty checking
)并生成并发出必要的SQL以便更新相应的DB记录确保DB记录与JVM中保存的相应实例具有相同的状态。
休眠会话的刷新行为由FlushMode
确定。默认情况下,它是FlushMode.AUTO
,这意味着在提交事务或执行查询之前将自动调用session.flush()
。因此,在您的代码中,虽然您没有显式调用session.flush()
,但仍会发生刷新过程以发出这些UPDATE语句。
关于代码的一些评论:
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();
答案 1 :(得分:1)
这是一种预期的行为。
get
返回的对象是持久性。对于持久对象,save
的调用基本上是被忽略的。但是Hibernate会自动跟踪持久对象中的更改并相应地更新数据库,因此update
语句。
答案 2 :(得分:0)
我认为这是因为您正在处理交易。当您提交事务时,它会自动刷新对已加载实体的任何更改,在本例中为您的Student对象 它不保存对象,因为它已经有一个附加到会话的唯一标识符 我原本以为Hibernate会抛出一个异常,因为你试图保存已经附加的对象。
我希望这可以帮助你。