3

生徒の情報を休止状態の 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();

データを保存して出力を確認すると、クラスの値が更新され、学生 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

データベースの学生クラスの値を更新する方法.save は、データを挿入することを意味します。しかし、ここで値が更新されます。

4

3 に答える 3

7

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

レコードが hibernate session によってロードされると、そのインスタンスは永続的な状態になり、このセッションによって管理されます。永続インスタンスの値が変更された場合、それらはダーティと見なされます。フラッシュ プロセス中 (つまりSession.flush())、hibernate はすべてのダーティ インスタンスを検出し (このプロセスを呼び出しますautomatic dirty checking)、必要な SQL を生成して発行し、対応する DB レコードを更新して、DB レコードが同じ状態になるようにします。 JVM に保持されている対応するインスタンスとして。

ハイバネート セッションのフラッシュ動作は、FlushMode. デフォルトでは 、トランザクションのコミットまたはクエリの実行前に自動的に呼び出されるのはFlushMode.AUTO which です。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();
于 2012-05-07T06:55:12.250 に答える
1

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

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

于 2012-05-07T06:29:59.460 に答える
0

トランザクションを扱っているからだと思います。トランザクションをコミットすると、既に読み込まれているエンティティ (この場合は Student オブジェクト) への変更が自動的にフラッシュされます。
セッションに関連付けられた一意の識別子が既にあるため、オブジェクトは保存されません。
すでにアタッチされているオブジェクトを保存しようとしたため、Hibernate が例外をスローしたと思いました。

これがお役に立てば幸いです。

于 2012-05-07T05:00:04.597 に答える