2011-08-03 10 views
0

私が言及した場合休止レイジー初期化の問題

以下の下で有名な遅延初期化の例外に出くわした休止状態について少し学んでいる間、私は別のクラスBへの参照を持っていると私はクラスAをロードしようとしていた休止状態使用しているクラスを持っていますそのIDを使用して、私はHibernateは、オブジェクトを初期化しているかもしれないが、それがなかったすべてのプロキシオブジェクトだったことを考えたクラスBのいくつかのプロパティを印刷しようとしていたセッションを閉じた後よりも、ここでのコードです。このコード

Session session=HibernateUtil.getSessionFactory().openSession(); 
     Transaction tx = session.getTransaction(); 
     try { 
      tx.begin(); 
      a=(A)session.load(A.class, "40288184318d9a3c01318d9a3eea0001"); 
      tx.commit(); 

     } catch (Exception e) { 
      log.error("Unable to complete the transcation" 
        + "Transcation will be roll backed", e); 
      e.printStackTrace(); 
      tx.rollback(); 

     } finally { 
      log.info("Closing the session"); 
      if (session != null && session.isOpen() == true){ 
       session.close(); 
      } 
     } 
     System.out.println(a.getUuid()); 
     System.out.println(a.getB().getShortDescription()); 
     System.out.println(a.getB().getLongDescription()); 
     System.out.println(a.getB().getName()); 

スナップ私はそれが私にBの代理人だけを与えたことを知っているので、私にorg.hibernate.LazyInitializationException: could not initialize proxy - no Sessionを与えていました。私はBの休止状態のプロパティを取得しようとしたときに例外

を投げる私は私のコードの小さな変化を行なったし、それはここでうまく働いていた。この場合、それが働いているが、私は確認していないのに変更されたバージョン

Session session=HibernateUtil.getSessionFactory().openSession(); 
    Transaction tx = session.getTransaction(); 
    try { 
     tx.begin(); 
     a=(A)session.load(A.class, "40288184318d9a3c01318d9a3eea0001"); 
     tx.commit(); 

    } catch (Exception e) { 
     e.printStackTrace(); 
     tx.rollback(); 

    } finally { 
     //log.info("Closing the session"); 
     if (session != null && session.isOpen() == true){ 
      b=des.getB(); 
      session.close(); 
     } 
    } 
    a.setB(b); 
    System.out.println(a.getUuid()); 
    System.out.println(a.getB().getShortDescription()); 
    System.out.println(a.getB().getLongDescription()); 
    System.out.println(a.getB().getName()); 
} 

です正しいアプローチであるかどうかをご提案ください

答えて

3

確かに正しいアプローチではありません。

Aを読み込み、Aに関連付けられたすべてのBを取得します。 あなたが行ったことを理解してください:Aを読み込んだ後、Bをbに設定します。 Bの値。

これを正しく行うにはいくつかのオプションがあります。

1)アプリケーションのビューフィルタで開いているセッションを使用します。一部の人々は、それを反パターンと見なしますが、多くの開発者がそれを行います。私は個人的にはその大丈夫と思います。

2)必要なものすべてを一度に取得できるカスタムクエリを作成します。

3)セッションがアクティブな間にa.getB()に電話をかけ、hibernateがあなたのためにそれをフェッチします。

4)アソシエーションを怠惰ではないようにしますが、遅くなるのでしません。あなたがAを得るときに常にBsを望むなら、あなたはそれを行うことができるが、その場合に限って。

+0

私はこれについて聞いたことがあり、それを試すことができます。第2のものに関しては、当時のカスタムHQLを避けたいと思います。私がしているすべてのことは間違っているかもしれないということをやっているのは、セッションクローズが私に参照を得ることを許可しないので、将来の使用のために別のオブジェクトにリファレンスを保存することです。 –

+0

ちょうど追加私はbこれは、 –

+0

@umeshの中のbの集合ではなく、aをロードした直後に 'a.getB()'を呼び出すと、将来、いつでも 'getB()'を呼び出すことができます。参照を保存する必要はありません... – hvgotcodes