2012-01-24 16 views
6

私はすでにStackoverflowでこの種の問題を見ていましたが、何も私の問題を解決するのには役に立たなかったでしょう。Hibernate、Java:セッションもセッションも閉じられていません

私はHibernateの初心者であり、JavaとMySQLで作成されたプロジェクトを持っているので、休止状態を使用しています。私は自分のデータにアクセスしてそれらを変更し、削除することに成功しましたが、私は到着した一つの例外があるのでメソッドをブロックしました。そして、私はこのバグを取り除かないことを私がまだ管理していないスレッドをすべて理解していることが分かりました:

org.hibernate.LazyInitializationException 墓:

はここに私の誤りである何のセッションまたはセッションが閉じられなかった org.hibernate.LazyInitializationExceptionを DAO.User.files、::怠惰な役割のコレクションを初期化に失敗しました失敗しました遅く初期化する ロールのコレクション:DAO.User.files、セッションもセッションも閉じられていません at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358) でorg.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350) org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollectionで.java:343) at org.hibernate.collection.PersistentSet.add(PersistentSet.java:189) at DAO.UserDAO.removeGroupAddUserFiles(UserDAO.java:252) javaapplication5.JavaApplication5.main(JavaApplication5.java:37 )

そして、ここに私のJavaクラスです:

public static void main(String[] args) { 
     GroupDAO grDAO = new GroupDAO(); 
     List[] lists = grDAO.removeGroup(grDAO.getGroupById(1)); 

     FileDAO fiDAO = new FileDAO(); 
     fiDAO.removeGroupAddFiles(lists); 

     UserDAO usDAO = new UserDAO(); 
     usDAO.removeGroupAddUserFiles(lists); 
    } 

GroupDAO.java:

public List[] removeGroup(Group group) { 
     Set<File> setFiles = group.getFiles(); 
     Set<User> setUsers = group.getUsers_1(); 
     List[] lists = new List[2]; 

     Iterator<File> itFiles = setFiles.iterator(); 
     Iterator<User> itUsers = setUsers.iterator(); 
     List<File> listFiles = new ArrayList<File>(); 
     List<User> listUsers = new ArrayList<User>(); 
     while (itFiles.hasNext()) { 
      listFiles.add(itFiles.next()); 
     } 
     while (itUsers.hasNext()) { 
      listUsers.add(itUsers.next()); 
     } 

     lists[0] = listUsers; 
     lists[1] = listFiles; 

     org.hibernate.Transaction tx = session.beginTransaction(); 
     session.delete(group); 
     tx.commit(); 

     return lists; 
    } 

FileDAO.java:

public List[] removeGroupAddFiles(List[] lists) { 
     System.out.println("5 : " + session.isOpen()); 
     System.out.println("6 : " + session.isOpen()); 
     Iterator<File> itFile = lists[1].iterator(); 
     System.out.println("7 : " + session.isOpen()); 

     org.hibernate.Transaction tx = session.beginTransaction(); 
     while (itFile.hasNext()) { 
      System.out.println("8 : " + session.isOpen()); 
      Iterator<User> itUser = lists[0].iterator(); 
      System.out.println("9 : " + session.isOpen()); 
      File f = itFile.next(); 
      while (itUser.hasNext()) { 
       System.out.println("10 : " + session.isOpen()); 
       System.out.println("11 : " + session.isOpen()); 
       User u = itUser.next(); 
       System.out.println("12 : " + session.isOpen()); 
       File fCopie = new File(u, f.getName() + "_" + u.getFirstName() + "_" + u.getLastName(), f.getExtension(), f.getSize(), f.getCreatedAt(), f.getUpdateAt()); 
       System.out.println("13 : " + session.isOpen()); 
       session.save(fCopie); 
       System.out.println("14 : " + session.isOpen()); 
      } 
     } 
     tx.commit(); 
     return lists; 
    } 

UserDAO.java:

public List[] removeGroupAddUserFiles(List[] lists) { 
     System.out.println("15 : " + session.isOpen()); 
     Iterator<User> itUser = lists[0].iterator(); 
     System.out.println("16 : " + session.isOpen()); 

     org.hibernate.Transaction tx = session.beginTransaction(); 

     while (itUser.hasNext()) { 
      System.out.println("17 : " + session.isOpen()); 
      Iterator<File> itFile = lists[1].iterator(); 
      System.out.println("18 : " + session.isOpen()); 
      User u = itUser.next(); 
      while (itFile.hasNext()) { 
       System.out.println("19 : " + session.isOpen()); 
       File f = itFile.next(); 
       System.out.println("20 : " + session.isOpen()); 
       try { 
        u.getFiles().add(f); 
       } catch (LazyInitializationException e) { 
        e.printStackTrace(); 
       } 
       System.out.println("21 : " + session.isOpen()); 
      } 
      try { 
       session.update(u); 
      } catch (ConstraintViolationException e) { 
       e.printStackTrace(); 
      } 
      System.out.println("22 : " + session.isOpen()); 
     } 
     tx.commit(); 
     return lists; 
    } 

私のコードがあります冗長、私は彼(それ)を知っている、それはエキスパートだった閉鎖したセッションの問題を回避しようとする。 ;

U.getFiles().add(F):

セッションは、ライン終了します

そしてHibernateUtil.java:

public class HibernateUtil { 

    private static final SessionFactory sessionFactory = buildSessionFactory(); 

    private static SessionFactory buildSessionFactory() { 
     try { 
// load from different directory 
      SessionFactory sessionFactory = new Configuration().configure("/hibernate.cfg.xml").buildSessionFactory(); 

      return sessionFactory; 

     } catch (Throwable ex) { 
// Make sure you log the exception, as it might be swallowed 
      System.err.println("Initial SessionFactory creation failed." + ex); 
      throw new ExceptionInInitializerError(ex); 
     } 
    } 

    public static SessionFactory getSessionFactory() { 
     return sessionFactory; 
    } 

    public static void shutdown() { 
// Close caches and connection pools 
     getSessionFactory().close(); 
    } 
} 

私は私のコードでどこでも)session.isOpenの表示を(置くだけでなく、エラーと格闘試してみます。こうしてプログラムは続行され、例外の前か後かにかかわらず、体系的に真実を示しています!

+0

あなたが 'u.getFiles()。add(f);'を実行する前に、removeGroupAddUserFilesメソッドの 'User u = itUser.next();' – Faton

+0

いいえ、私はそれを見る方法がわからないので試していませんでした: – algelos

答えて

10

一般的な問題は、トランザクションを開いて、FetchTypeLAZYでHibernateオブジェクトを作成することです。 Hibernateは、コレクションの最初の使用時にオブジェクトをロードするコレクション用のプロキシを作成します。トランザクションをクローズし、そのコレクションにアクセスしようとしました。トランザクションが閉じられているため、Hibernateセッションは期限切れです。エラーが発生しました。

トランザクションブロックからユニット化されたプロキシを持つオブジェクトを決して返さないように、コードを再設計する必要があります。コレクションからコレクションまたはevictオブジェクトをロードするか、コレクションを自動的に(POJOから削除する)マッピングしないでください。

+4

あなたは何を意味するのか分かりません。私は実際にはHibernateのnoobです。 – algelos

+0

org.hibernate.Transaction tx = session.beginTransaction(); tx.commit(); –

2

あなたのアプリケーションに直接Hibernateプロキシエンティティを保存すると、セッションがライブになるまで利用可能になります。セッションが閉じられると、これらのエンティティにアクセスすることはできません。あなたがトランザクションを閉じた後にそれらを使用するintentedされている場合は、トランザクションを閉じた後にそれらにアクセスしようとした場合、あなたはこの

org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException 

を取得しますだから、あなたプロキシエンティティの新鮮なコピーを作成することは常に良いです。

-2

web.xmlに次の行を追加することで、LazyInitilization例外を修正できます。

<filter> 
    <filter-name>OpenSessionInViewFilter</filter-name> 
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> 
</filter> 

<filter-mapping> 
    <filter-name>OpenSessionInViewFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

訪問:http://blog.gmorales.net/2012/03/how-to-solve-orghibernatelazyinitializa.html

関連する問題