2009-07-16 11 views
2

私は、クエリから返されたHibernateオブジェクトが信頼できない状況に遭遇しました。信頼できないHibernateオブジェクト

は、次のコードを考えてみましょう:

MyClass myClass = myDAO.get(id); 

myClass.getId(); //This works 
myClass.getName(); //This returns null sometimes, and works sometimes 

ここに私のgetメソッドです:

@SuppressWarnings("unchecked") 
public T get(ID id) 
{ 
    Session s = getSession(); 
    T entity = (T) s.load(getPersistentClass(), id); 
    s.disconnect(); 
    return entity; 
} 

は今、私はこのオブジェクトがプロキシで、遅延ロードになることを理解し、私はそれを期待します常に働くか、働かないかのどちらかです。私はここで何か間違っていますか?

答えて

3

これは原因である場合もありませんが、Session.load()を使用しないでください。Session.get()を使用する必要があります。

load()は、現在hibernateによってロードされている永続インスタンスを返します。これは以前に何が起きたかによって部分的に設定される可能性があります。

get()はより堅牢です。それを試してください。

+0

(ハイバネートチームの推奨に従って)パフォーマンス上の理由からload()が使用されています。私はget()ショットを与えますが、私はまだそれを求めるときにメンバーをフェッチするために休止状態を期待します... – Jesse

+1

ロードを使用して同じ問題ではない場合、私はget()に変更し、 ) – jottos

+0

私はこれを答えとしてマークしています。私は少し前にload()からget()に変更して以来、問題はありませんでした。 – Jesse

1

問題は、 "load"はオブジェクトのプロキシをロードし、実際にデータベースにヒットしないことです。しかし、オブジェクトが既にロードされている場合(および移入されている場合)、つまりレベル1のキャッシュには、そのインスタンスがプロビジョニングされます。

loadを使用すると、絶対に必要なとき、つまりオブジェクトのフィールドの1つを尋ねるときに、実際にデータベースにヒットするだけです。

他の手で実際にデータベースにヒットします。

あなたの目的に合わせて、loadを使用するかどうかにかかわらず、オブジェクトを戻す前にオブジェクトが移入されていることを確認することをお勧めします。それを戻す前に、ゲッターの1人に電話してください。それで、それが占有されていることを保証することができます。

SQLロギング(org.hibernate.SQL = DEBUG)を有効にし、それをデバッグし、実行されているsql命令を見てみましょう。

読み込み中の永続オブジェクトを非遅延に設定することも考えられます。そうすることで、loadかgetかにかかわらず、毎回完全にオブジェクトが作成されます。

+0

あなたが提案したように、私はhibernateマッピングでeager fetchingを有効にしないでください。デフォルトで読み込みを行うと、マップされたクラスのコレクションをロードするときや、マップされたクラスのすべてのフィールドを表示する必要のないビューをクエリするときに、パフォーマンスが大幅に低下する可能性があります。これは、Hibernate 3.xでのデフォルトの遅延ロードです –

関連する問題