2009-04-21 11 views
0

私はNetBeansでHibernateを使用しています。私は現在のセッションを取得するためにNetBeans用のHibernateプラグインに付属のハイバネートutilクラスを使用しています。hibernate session problem new

org.hibernate.LazyInitializationException: failed to lazily initialize a course.

私は2 DAOを使用しています:私はそれが次のエラーを与える何かをフェッチ怠惰にしようとすると、

this.session = HibernateUtil.getSessionFactory().getCurrentSession(); 

しかし:それは私が私の現在のセッションを取得するには、次のコードを使用しています、です。 1つは抽象DAOであり、2つ目はAbstractDAOを拡張するCoutseDAOです。

public class AbstractDAO<T> { 


    Session session = null; 


    public AbstractDAO() 
    { 
     this.session = HibernateUtil.getSessionFactory().getCurrentSession(); 

    } 

    public void createObject(T object) 
    { 
     Transaction tx = null; 
     try 
     { 

      tx = session.beginTransaction(); 
      session.save(object); 
      tx.commit(); 

     } 
     catch (HibernateException e) 
     { 
      tx.rollback(); 
      throw new DataAccessLayerException(e); 

     } 
     finally 
     { 


     } 
    } 
    public void updateObject(T object) 
    { 
     Transaction tx = null; 
     try 
     { 

      tx = session.beginTransaction(); 
      session.update(object); 
      tx.commit(); 

     } 
     catch (HibernateException e) 
     { 
      tx.rollback(); 
      throw new DataAccessLayerException(e); 

     } 
     finally 
     { 


     } 
    } 

     public void deleteObject(T object) 
    { 
     Transaction tx = null; 
     try 
     { 

      tx = session.beginTransaction(); 
      session.delete(object); 
      tx.commit(); 

     } 
     catch (HibernateException e) 
     { 
      tx.rollback(); 
      throw new DataAccessLayerException(e); 

     } 
     finally 
     { 


     } 
    } 

} 

第classsを次のように コードは以下の通りである

public class CourseDAO extends AbstractDAO<Course>{ 

    public CourseDAO() 
    { 
     super(); 
    } 

    public Course findByID(int cid){ 


     Course crc = null; 
     Transaction tx = null; 
     try { 
      tx = session.beginTransaction(); 
      Query q = session.createQuery("from Course as course where course.cid = "+cid+" "); 
      crc = (Course) q.uniqueResult(); 
      tx.commit(); 
     } 
     catch (HibernateException e) 
     { 
      e.printStackTrace(); 
      tx.rollback(); 
      throw new DataAccessLayerException(e); 
     } 

     finally 
     { 


     } 
     return crc; 
} 


    public List<Course> findAll(){ 

     List lst = null; 
     Transaction tx = null; 
     try { 
      tx = session.beginTransaction(); 
      Query q = session.createQuery("from Course "); 
      lst = q.list(); 
      tx.commit(); 
     } 
     catch (HibernateException e) 
     { 
      e.printStackTrace(); 
      tx.rollback(); 
      throw new DataAccessLayerException(e); 
     } 

     finally 
     { 



     } 
     return (List<Course>)lst ; 
} 







} 
+0

セッションを取得する方法だけでなく、DAOをロードするために使用する完全なコードを投稿する必要があります。 – Elie

+0

これは、Hibernateが意図した作業を行うために、DAOを誤って誤って使用しているように見えます。 'createObject(Tオブジェクト)'は、Hibernateが作業を行うべきところでクエリの長​​さを書いています。トランザクションの境界はDAOメソッドの境界で終わっています..すべてが完全に間違っています。 DAOのすべてのものを取り除き、Hibernateを直接使用してください。 –

答えて

-1

「古い」オブジェクトの犠牲者である可能性があります。 Seamを使用する場合、私は注射されたオブジェクトに対してこの問題があります。当社のソリューションは、呼び出しのように、使用する前に、メインオブジェクトを再フェッチしてきました:あなたは私たちのアクションクラスでメソッドを呼び出すたび

getEm().find(MyClass.class, id); 

基本的には、あなたがオブジェクトではないことを確認するためにこれを実行する必要がありますあなたの現在のセッション/トランザクションで失効します。

また、例外(キャッチしたとしても)は、現在のセッションを閉じてLazyInitializationエラーを引き起こす可能性があります。

+0

問題は彼のすべてのDAOメソッドに彼のパットTXの境界です。これにより、遅延読み込みオブジェクトの問題が保証されます。 –

0

遅延フィールドは、オブジェクトをフェッチトランザクションの境界内でアクセス可能です。

+0

私は私のプロンプトのためのDAOの実装を提案することができます – user93796

0

hibernateが同じトランザクション内の遅延フェッチのクエリを実行できるようにトランザクションマネージャを設定する必要があります。

Hibernateのサイトがダウンしているようだが、GoogleはHibernate設定でスレッドに結びついた戦略を有効にするにはcache

があります

JPA、EJBまたはローリングのような他のオプションがありますが、
set hibernate.transaction.factory_class to org.hibernate.transaction.JDBCTransactionFactory 
set hibernate.current_session_context_class to thread 

あなた自身の。

アプリケーションサーバーで実行していない場合や、他の方法でトランザクションを処理するその他のものを使用している場合は、コードを「手動で」トランザクションを開始する必要があります。

try { 
    factory.getCurrentSession().beginTransaction(); 

    // Do some work 
    factory.getCurrentSession().load(...); 
    factory.getCurrentSession().persist(...); 

    factory.getCurrentSession().getTransaction().commit(); 
} 
catch (RuntimeException e) { 
    factory.getCurrentSession().getTransaction().rollback(); 
    throw e; 
} 
+0

このオプションはどこで設定できますか? hibernate.cfg.xmファイルにあります。もしそうなら、どのように? – user93796

+0

このパラメータを設定しようとしましたが、同じコードで動作しません – user93796

+0

何かをする前にトランザクションを開始する必要があります。 少し複雑なので、ドキュメントを読もうとしてください。 Googleキャッシュのリンクを試してみてください。 – KarlP

0

これは、Hibernateが意図した作業を行うために、DAOをひどく誤って使用しているようです。 Hibernateは、作業を行うことができる場所

  1. トランザクション境界が
  2. あなたは手書きのクエリを書くべきではありません。.. DAOメソッド境界で終了しない、
  3. findByIdは()だけでセッションへの呼び出しでなければなりません.load(Course.class、id)。
  4. createObject(T object)は間違っています。それは '保存'する必要があります。
  5. exception-catchingも間違って配置されています。 Tx境界上になければならない。

すべてが完全に間違っている、それは絶対的なひどいです、あなたが書いたものはすべて間違っています&は不要です。あなたはこれがすでに完了しているときに、JDBCの&トランザクション管理を書こうとしています。

はここにあなたのコードが行くべき方法は次のとおりです。

Session hb = sf.openSession(); // or wherever you get a Session from 

// load by ID 
Course course = (Course) hb.load(Course.class, id); 

// list all courses 
Criteria crit = hb.createCriteria(Course.class); 
List<Course> allCourses = crit.list(); 

// create a new Course 
Course newCourse = new Course("Hibernate 101"); 
hb.save(newCourse); 

// delete the old one 
hb.delete(course); 

// flush & commit all changes, in a transaction. 
Transaction tx = hb.beginTransaction(); 
/* hb.flush() */ 
tx.commit(); 

はあなたがやっていることを知ってまで、このDAOはゴミ&使用は、直接休止すべてを取り除きます。 DAO /ビジネスメソッドは、単純であり、トランザクション/例外管理を行わないようにしてください。彼らは内で実行します。