2012-05-07 20 views
3

学生情報をhibernate session.save()に保存するためのコードをサンプルしようとしています。その中で、学生名、クラス、教師ID。Session.saveは休止状態のデータを更新しています

表:学生

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のように更新された出力を見ては、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はデータを挿入することを意味しますが、ここでは値が更新されます。私は知っています。何か問題がある場合.if任意の間違った質問申し訳ありません。

答えて

7

これはHibernateの予想される動作です。

レコードが休止状態セッションによってロードされると、そのインスタンスはpersistent状態になり、このセッションによって管理されます。永続インスタンスの値が変更された場合、それらはダーティとみなされます。フラッシングプロセス中に(つまりSession.flush())、hibernateはすべてのダーティインスタンス(このプロセスはautomatic dirty checkingと呼ばれます)を見つけ出し、対応するDBレコードを更新するために必要なSQLを生成して発行し、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(); 
+0

非常に徹底した説明。私にいくつか教えてください。 :) – Falle1234

+0

自動汚れチェックとは何ですか? – user1357722

+0

Hibernateは、永続オブジェクトの状態変化を自動的に追跡し、フラッシュ中にダーティオブジェクトを更新します。この能力を説明するための単なる言葉です –

0

あなたはトランザクションを使って作業していると思います。トランザクションをコミットすると、既にロードされているエンティティ(この場合はStudentオブジェクト)への変更が自動的にフラッシュされます。
オブジェクトにはセッションに固有の識別子がすでに割り当てられているため、オブジェクトは保存されません。
すでに接続されているオブジェクトを保存しようとしたため、Hibernateが例外をスローしたと思います。

私はこれがあなたを助けてくれることを願っています。

1

これは予想される動作です。

getによって返されるオブジェクトは、の持続型です。永続オブジェクトに対するsaveの呼び出しは、基本的には無視されます。しかし、Hibernateは永続オブジェクトの変更を自動的に追跡し、それに応じてデータベースを更新します。したがって、updateステートメント。

+0

保存は自動的にダーティcheckingso経由でも更新を行いますので、我々はするsaveOrUpdate権利を必要としません? saveOrUpdateがsaveより優先される状況がある – Anand