2009-06-02 23 views
0

誰でもコレクションのロードや多対1のアソシエーションのロードを防ぐ方法を知っていますか?休止状態でのプロパティ/コレクションのロードを無効にする

私はオブジェクトをロードする必要があるユースケースがありますが、呼び出し側のプログラムは特定のプロパティがロードされているかどうかを判断できます。コレクションの一部についても同じことが起こります。特定の行をフェッチする必要があります。

ドメインクラス:

public class SomeClass { 
    private SomeClass parent; 
    private Set<OtherClass> collection; 
} 

public class OtherClass { 
    private Date startDate; 
    private Date endDate; 
} 

public class Dao { 
    public SomeClass loadClass(long id, boolean parents, boolean historicalData) { 
     // load SomeClass 
     // if parents == true, load parent, otherwise leave <null> 
     // if historicalData == false, load OtherClass where endDate == <null> 
    } 
} 

私は2つのソリューションを考えているが、基準またはクエリとその可能な場合、私は今にONT。

解決策1は、SomeClassからOtherClassへのアソシエーションと、Hibernate構成における親子関係を行い、コード内でアサーションをロードしません。
解決策2は、特殊なケースに対応して異なるエンティティ名で異なるマッピングを定義することです。

この場合、呼び出し側は他のJVMまたはトランザクション内にある可能性があるため、セッションは閉じられているため、遅延ロードは実際のオプションではありません。

答えて

1

Criteriaクエリを作成し、setFetchModeメソッドを使用して、parentおよびcreateCriteriaメソッドのフェッチ動作を変更してコレクションを追加クエリします。

Criteria c = session.createCriteria(SomeClass.class).add(Restrictions.idEq(id)); 

if (parents) { 
    c.setFetchMode("parents", FetchMode.EAGER); 
} 
if (historicalData) { 
    c.createCriteria("collection", Criteria.LEFT_JOIN) 
    .add(Restriction.lt("date", date)) 
    .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 
} 
return c.uniqueResult(); 

...これは、デフォルト設定がLAZY(Hibernateのデフォルト)ですと仮定しています。

なお、この場合には(多対一の関連付けを値を持たないヌルの特性を残すために休止状態にはオプションではありません。フィールドを遅延参照されるオブジェクトをロードするために使用することができるプロキシを保持します。コードがオブジェクトに触れることがない場合は、ロードされません。

コレクションにも同じことが言います。フェッチされない場合、コレクション・プロキシー(コレクション・インターフェースを実装するhibernateクラス)が保持されます。

+0

私はこの解決策を考えています。それを文書化するか、またはヌルにロードされないプロパティーを手動で設定するだけです。 – Salandur

2

これには、Hibernateの遅延ロード機能を活用する必要があります。あなたが実際にコードでアクセスした場合、Hibernateはコレクションのみをロードする場合

@OneToMany(fetch=FetchType.LAZY) 

: あなたのようなコレクションに注釈を付けることができます。

+0

オブジェクトがクライアントに返され、プロパティがアクセスされるかどうかを制御できません。別のJVMまたはトランスで実行される可能性があります。アクション。私は質問でそれを明らかにするでしょう。 – Salandur

+0

その場合は、あなたのユースケースに基づいて作成したデータ転送オブジェクトを使用することをお勧めします。 –

0

上記のポスターのように@OneToMany(fetch=FetchType.LAZY)を使用してください。ただし、Hibernate 3.xのデフォルトのフェッチタイプは、Collections and Associationsの遅延フェッチです。

0

私は#2が最善の解決策だと思います。私はこのソリューションを自分で使っていませんが、成功した他の開発者を知っています。