項目中使用Hibernate時報了一個異常:org.hibernate.NonUniqueObjectException;經從網上查找資料得知,同一個session裏面有了兩個相同標識可是是不一樣實體.即2個不一樣的對象關聯到了同一個標誌位。java
驗證代碼以下:sql
@Test public void add() { Session session = SessionFactory.getSession(); Transaction tr = session.beginTransaction(); // ---------------------------------------------- Person p1 = (Person) session.get(Person.class, 0); Person p2 = new Person(); p2.setId(0); p2.setName("username" + p1.getName()); session.update(p2); // ---------------------------------------------- tr.commit(); SessionFactory.closeSession(); }
執行報出異常:數據庫
解決方案:使用session.merge()方法代替update()方法。session
當調用update或saveOrUpdate操做時,拋出了異常信息「org.hibernate.NonUniqueObjectException」,不是「獨一無二」的對象。爲何會拋出這個錯誤呢?上面的person2調用了get方法,因此person2是一個持久化對象,當在session尚未關閉的時候對person2作的任何修改,都會保存到數據庫中;person要執行更新操做,但因爲它是一個脫管對象,那麼就須要跟數據庫從新取得聯繫,須要從數據庫獲取數據,hibernate會查找當前是否關於這個對象的副本,恰好有個person2(但又不知person2是否修改了且保存到了數據庫),與其保存這可能沒用的數據,還不如直接報錯來得直接。這裏調用update和saveOrUpdate相似。.net
還有update與merge的一點不一樣是:update是直接發出「sql update」語句,而merge會先發出「sql select」語句,若是沒有查詢到結果,那麼執行save操做,若是查詢到相關結果,則判斷對應字段是否有發生改變,若是改變了,則發出「sql update」語句,不然什麼也不作。這一方面,merge就和saveOrUpdate相同。hibernate
參考文章:code
http://blog.csdn.net/zhongxianyao/article/details/12294011對象
http://www.simplecodestuffs.com/difference-between-update-and-merge-methods-in-hibernate/blog