本文與上一篇文章的軟件背景相同,是一個安裝部署的工具,這個工具會生成整套系統部署用的xml文件。html
這個工具中有一個「克隆」功能,當安裝包有新版本後,能夠克隆以前的xml版本,並在其基礎上作少量修改來適配新版本的功能。數據庫
今天遇到的問題就是在克隆階段。session
問題現象:
只有在克隆其中一個產品時會發生以下圖所示的錯誤,其餘的產品克隆功能是正常的:ide
"a different object with the same identifier value was already associated with the session:2, of entity: "工具
![](http://static.javashuo.com/static/loading.gif)
經過上面的錯誤信息,可以很明確的知道是Hibernate報出的錯誤。hibernate
解決思路:
- 由錯誤信息能看出,應該是主鍵衝突,所以首先定位到是由哪條記錄致使的主鍵衝突
- 報錯的對象是ValidationType類,ValidationType是數據庫初始化建立的數據,無需增刪改操做
- 錯誤日誌中沒有找到有用的信息。根據調試代碼和數據庫變化,追蹤是哪條記錄致使的主鍵衝突
- 只有一個產品的克隆出現問題,其餘的產品都是好的,對比產品的差別,並根據3調試跟蹤
根源查找:
- 根據產品xml對比,「克隆」出錯的產品,在參數、安裝包、驗證模塊都比其餘的多不少
- 根據調試和數據庫記錄的變化看來,克隆雖然報錯,但產品基本信息、安裝包等都插入數據庫成功,驗證模塊部分插入成功,因此極可能是驗證模塊致使的主鍵衝突
- 檢查驗證模塊的業務,共有8個驗證模塊,每次都是僅插入了前3條,因此極可能問題出如今第4條和以後
- 發現第4條和第5條的驗證模塊用了相同的ValidationType,ValidationType是在數據庫初始化時插入的,不該該有增刪改的操做,查看Hibernate的配置找到問題根源cascade=「save-update」,以下圖:
![](http://static.javashuo.com/static/loading.gif)
問題分析(cascade=「save-update」):
由於ValidationType是數據庫初始化時的數據,不須要增刪改,因此應該設置爲none模式,若是設置爲「save-update」時,hibernate會對他們的ValidationType進行saveorupdate操做,當有兩個相同的ValidationType時就出現了主鍵衝突的錯誤了。下面是對cascade配置的詳細解讀調試
元素的cascade屬性代表操做是否從父對象級聯到被關聯的對象, 它的取得能夠是如下幾種:日誌
- none:在保存,刪除或修改當前對象時,不對其附屬對象(關聯對象)進行級聯操做。它是默認值。
- save-update:在保存,更新當前對象時,級聯保存,更新附屬對象(臨時對象,遊離對象)。
- delete:在刪除當前對象時,級聯刪除附屬對象。
- all:全部狀況下均進行級聯操做,即包含save-update和delete操做。
- delete-orphan:刪除和當前對象解除關係的附屬對象。
更多關於Hibernate中的配置,能夠參考連接:https://www.cnblogs.com/little-fly/p/2017-01-05.htmlxml