2012-06-27 4 views
6

ポリモーフィズムがサポートされるように、ハイバネートオブジェクトのプロキシ解除を解除するにはどうすればよいですか?hibernateオブジェクトをプロキシ解除する方法

次の例を考えます。クラスAとクラスBは、2つの休止状態のエンティティです。 Bは、このコードはBコレクションがロードされた遅延され、Bのすべてのインスタンスが休止プロキシであるため、CまたはDブロックのいずれかを実行することができない2つのサブタイプC及びD

List<A> resultSet = executeSomeHibernateQuery(); 
for(A nextA : resultSet) { 
    for(B nextB : nextA.getBAssociations() { 
     if(nextB instanceof C) { 
      // do something for C 
     } else if (nextB instanceof D) { 
      // do something for D 
     } 
    } 
} 

を有しています。私は各インスタンスのプロンプトを解除する方法が欲しいです。

注:すべてのBを熱心に取得するようにクエリを最適化することができます。私は代替案を探しています。

+1

私はそれが古い質問だと知っていますが、Google検索の最初の結果として現れたので、 'instanceof'を使用する必要がある場合は、おそらく多型が間違っているとコメントしなければなりません。 – drigoangelo

答えて

18

は、ここに私たちのソリューションです、私たちの永続utilsのに追加:HibernateProxyとgetImplementationMethodを使用して

public T unproxy(T proxied) 
{ 
    T entity = proxied; 
    if (entity instanceof HibernateProxy) { 
     Hibernate.initialize(entity); 
     entity = (T) ((HibernateProxy) entity) 
        .getHibernateLazyInitializer() 
        .getImplementation(); 
    } 
    return entity; 
} 
+0

このソリューションはあなたのために働いていますか?私は同様のメソッドを実装していますが、私はまだオブジェクトのクラスとして 'HibernateProxy'を持っています。ここに私の質問です:http://stackoverflow.com/q/11518091/845220 – woyaru

+0

これは、 'PersistentCollection'の問題を扱っていません。通常、 'List 'は 'PersistentCollection'として実際にプロキシされています。このメソッドを渡すと、テストの 'entity instanceof HibernateProxy'は失敗し、何もせずにメソッドが返ります。解決策は、 'entity instanceof PersistentCollection'をテストし、' Hibernate.initialize() 'も使用し、コレクションのすべてのオブジェクトを反復してアンプロキシすることです。しかし、実装するよりも記述が簡単です。 – Aldian

+1

エンティティがnullでないことを確認する必要はありません(http://stackoverflow.com/questions/2950319/is-null-check-needed-before-callingを参照してください)。 -instanceof) – laurent

2

ソリューションが正しいです。

しかし、私はあなたのコレクションがインターフェイスとして定義されており、ハイバネートがプロキシをインターフェイスに提示しているので、あなたはこれを実行していると仮定します。

これは、インターフェイスメソッドを使用して必要なことをする代わりに、 "if"を "instanceof"とする設計上の問題につながります。

だからあなたのループは次のようになります。

for(B nextB : nextA.getBAssociations() { 
    nextB.doSomething(); 
} 

そのように、休止状態は、実際の実装オブジェクトへ「のdoSomething()」への呼び出しを委任だろう、とあなたは違いを知っていることはありませんでした。

+0

良い点はすべて、継承の使用はおそらく理想的ではありません。この特定のケースでは、実際にはコレクション内の各アイテムのタイプに応じて他のロジックがあります。ですから、isC()とisD()抽象メソッドを追加することもできましたが、やはりちょっとした感じがしました。 FWIW、私たちの階層は、ほとんどのユースケースで機能しますが、これは20%の一部です。 –

関連する問題