1

以下のコードを試しました:

Student s1 = (Student) s.load(Student.class, 5); // this records not there in DB
 try {
    s1.setName("Kaushik1");
} catch (ObjectNotFoundException e) {
    s1 = new Student();
    s1.setId(5);
    s1.setName("trying1");
}
s.saveOrUpdate(s1);

Student s2 = (Student) s.load(Student.class, 5);
try {
    s2.setName("Kaushik2");
} catch (ObjectNotFoundException e) {
    //Why should it throw ObjectNotFoundException now
    s2 = new Student();
    s2.setId(5);
    s2.setName("trying2");
}
s.saveOrUpdate(s2); //Why it throws NonUniqueObjectException

以前loadは ID#5 で DB からレコードを取得していました。レコードが存在しません。次に、オブジェクトでセッターを呼び出してみましたが、例外がスローされました。同意!!

レコードが存在しなかったので、新しいオブジェクトを作成して呼び出しsaveOrUpdate()ました。したがって、ID#5 のオブジェクトがセッション キャッシュにあると仮定します。

load()ここで、ID#5 のメソッドを再度呼び出し、そのセッターを呼び出します。再度 ObjectNotFoundException をスローします。

質問1

セッションキャッシュからレコードを選択できないのはなぜですか?

新しいオブジェクトを作成して呼び出そうとするとsaveOrUpdate()NonUniqueObjectException

org.hibernate.NonUniqueObjectException: 同じ識別子値を持つ別のオブジェクトが既にセッションに関連付けられていました: [com.cts.closr.Student#5]

ObjectNotFoundException がスローされ、「オブジェクトは既にセッションに関連付けられています」と表示されるようになりました。それは矛盾していませんか?

質問2

load()メソッドがセッションコンテキストをチェックしないということですか?常にDBからフェッチしますか? そのような場合、get() メソッドを使用する必要がありますか?

4

2 に答える 2

4

ドキュメントには次のように記載されています。

Session が例外 (SQLException を含む) をスローした場合は、すぐにデータベース トランザクションをロールバックし、Session.close() を呼び出して、Session インスタンスを破棄します。Session の特定のメソッドは、セッションを一貫した状態のままにしません。Hibernate によってスローされた例外は、回復可能として扱うことはできません。

したがって、 を使用しSession.load()、例外をキャッチし、セッションを使用し続けることは、絶対にダメです。Session.load()オブジェクトがデータベースに存在する必要があると考える場合に使用する必要があり、存在しない場合は例外をスローする必要があります。オブジェクトが存在するかどうかわからない場合は、 を使用してSession.get()、返されたオブジェクトが null かどうかをテストし、それに応じて対処します。

于 2013-01-26T08:09:37.563 に答える
0

「今、ID#5 の load() メソッドをもう一度呼び出してみます」と入力すると、間違っていると思います。

    Student s2 = (Student)s.load(Student.class, 6); 

すべきか

    Student s2 = (Student)s.load(Student.class, 5);

?

于 2013-01-25T06:05:17.093 に答える