2016-05-13 68 views
0

在我們的JSF應用程序中,我們不時遇到類型爲org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session的Hibernate NonUniqueObjectException。在大多數情況下,這些錯誤是由於以下情形:如何在Hibernate 3中調試NonUniqueObjectException?

  1. 負載從數據庫中的對象
  2. 調用業務邏輯
  3. 業務邏輯的內心深處,有一個隱藏的其他調用重新加載相同對象的數據庫。
  4. 修改原始對象並嘗試保留它
  5. 獲取異常。

現在由於該應用程序非常大,通常很難確定何時完成對數據庫的第二次調用。即使使用sql跟蹤,也可能發生多次調用,我仍然需要找出好的調用。

什麼是更好的將能夠調用該方法checkUniqueness從代碼中的任何位置拋出異常,但似乎沒有任何簡單的捷徑。有誰知道一個竅門?

回答

0

考慮看看到Hibernate源代碼後,我寫了下面的類:

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"; 
    } 
} 

請注意,您必須配置任何初始化你的應用程序(例如彈簧),以便它注入了一個SessionFactory在相應的bean 。

我打電話從Eclipse中Expressions視圖此方法:例如我使用用表達

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

在大多數情況下它打印OK或關於消息的評估一步步進展該對象已經關聯但沒有找到條目。但是當它更改爲NonUniqueObjectException的文本時,我確切知道在哪裏挖掘以找出數據庫的罪魁禍首。

希望這會幫助其他人與古怪的Hibernate異常鬥爭..