我在服務類中有以下代碼。作爲功能的一部分,此代碼從兩種不同的方法中調用兩次。Hibernate給org.hibernate.NonUniqueObjectException並將過時的對象保存到數據庫
//Some code here...
LOG.info("###Inside customer interceptor");
try
{
customerDao.save(customer);
}
catch (final Exception exp)
{
//some code here too...
}
當它從第一個方法調用和執行第一次,我可以看到,有在Tomcat的控制檯打印的選擇SQL語句,但沒有更新SQL語句,如我所料(可能是因爲事實上,Hibernate不會立即發佈插入/更新)。 立即當從第二個方法再次調用這個代碼塊時,我看到一個SQL select語句,然後在tomcat控制檯中看到一條SQL update語句,之後我立即看到一個大胖子org.hibernate.NonUniqueObjectException。 這是我可以理解的,因爲先前的實體仍然附加到會話並且沒有提交給DB。
但是,當我去看看數據庫時,我發現保存在數據庫中的值是第一次調用的對象,而不是我預期的第二次調用的對象。這是正常的還是我在這裏錯過了一些東西?
我使用Spring的註解(@Transactional)驅動的事務策略。
謝謝宙斯。是的,爲了測試目的,我嘗試使用merge()作爲其他帖子的建議,它確實保存了新的對象而不是過時的,並且我沒有得到nonUniqueObject異常。然而,我的問題更多的是要理解爲什麼儘管在方法級使用@Transactional,爲什麼它在方法執行結束後沒有提交,其次爲什麼在調用save方法而不是當前的過時對象被保存在數據存儲中。 –
我可能需要了解打電話是如何回答你的問題的。如果使用同一個會話來更新兩個具有相同ID的客戶對象,那麼您將得到該異常非唯一異常。在你的代碼的某個地方,會話沒有關閉,所以你第一次保存,沒有錯誤,第二次它會給出錯誤,因爲會話已經有了這個對象。另外,保存用於存儲瞬態對象而不是分離對象。 – Zeus
嗯......我在Hybris電子商務平臺內部使用了這段代碼,而且這段代碼在Interceptor類內部,每當與這個攔截器相關的模型發生任何變化時都會觸發它。當然,我正在使用googlecode實現hibernate,其中save()正好完成saveOrUpdate()在其他Hibernate實現中的作用。 –