2016-05-13 7 views
0

JSFアプリケーションでは、時々Hibernate NonUniqueObjectException(種類がorg.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session)が発生します。時間のほとんどは、これらのエラーは、次のシナリオに起因するものである:ビジネス・ロジックのデータベース Hibernate 3でNonUniqueObjectExceptionをデバッグする方法は?

  • コールビジネスロジック
  • 深い内側から

    1. ロードオブジェクトを、に隠された他の呼び出しがあります同じオブジェクトをリロードするデータベース
    2. 元のオブジェクトを変更して永続化してください。
    3. 例外を取得します。

    アプリが非常に大きいので、データベースへの2回目の呼び出しが完了した時点を把握することは難しいことがあります。 SQLトレースを使用していても、いくつかのコールが存在する可能性があり、それでも良いものを見つける必要があります。

    コード内のどこからでも例外をスローするそのメソッドcheckUniquenessを呼び出すことができればいいですが、簡単なショートカットがないようです。誰かがトリックを知っていますか?

    import org.hibernate.SessionFactory; 
    import org.hibernate.engine.EntityKey; 
    import org.hibernate.event.EventSource; 
    import org.hibernate.persister.entity.EntityPersister; 
    
    /** 
    * @author aldian 
    * 
    */ 
    public class HibernateDebug { 
        private static SessionFactory sessionFactory; 
    
        public static SessionFactory getSessionFactory() { 
         return sessionFactory; 
        } 
    
        public void setSessionFactory(SessionFactory sessionFactory) { 
         HibernateDebug.sessionFactory = sessionFactory; 
        } 
    
        public static String checkUniqueness(Object entity, Long id) { 
         try { 
          org.hibernate.classic.Session currentSession = sessionFactory.getCurrentSession(); 
          if (currentSession instanceof EventSource) { 
           EventSource eventSource = (EventSource) currentSession; 
           eventSource.getPersistenceContext().unproxyAndReassociate(entity); 
           EntityPersister persister = eventSource.getEntityPersister(entity.getClass().getName(), entity); 
    
           EntityKey key = new EntityKey(id, persister, eventSource.getEntityMode()); 
           eventSource.getPersistenceContext().checkUniqueness(key, entity); 
           return "OK"; 
          } 
         } catch (Exception e) { 
          return e.getMessage(); 
         } 
         return "NOT OK"; 
        } 
    } 
    

    注それが対応するBeanでのSessionFactoryを注入するようにします(例えば、バネ用)にアプリを初期化するものは何でも設定する必要があります。

  • 答えて

    0

    は、ソースコードをHibernateに見て取った後、私は次のクラスを書きました。

    私は、EclipseからExpressionsビューからこのメソッドを呼び出しています:たとえば、私は表現の時間のほとんど

    com.mycompany.hibernate.HibernateDebug.checkUniqueness(entity,entity.getId()) 
    

    それはOK印刷したりメッセージについての評価のステップの進行によってステップを使用していますオブジェクトはすでに関連付けられていますが、エントリが見つかりませんでした。しかし、それがNonUniqueObjectExceptionのテキストに変わったとき、私はデータベースへの犯人呼び出しを見つけるためにどこを掘るべきか正確に知っています。

    これは、古い奇妙なハイバーネーションの例外と闘う他の人に役立つと期待しています。