1. 程式人生 > >hibernate jpa manyToOne級聯操作時,update時報出identifier of an instance of 問題的解決方案及update問題

hibernate jpa manyToOne級聯操作時,update時報出identifier of an instance of 問題的解決方案及update問題

   最近一直在用Jpa來做專案,jpa的優點這裡我就不多說了,說一下最近使用時解決的一個問題吧。

首先來說,使用jpa進行update操作時,由於呼叫的是jpa封裝好的save方法,所以如果表單頁面中沒有提到的引數,這時儲存的時候,沒有提到的引數就會被置為null,為此我想到的第一種解決方案就是把查詢出來的資料寫到頁面表單的隱藏域中,可是這樣以來,一些需要保密的資料就外洩了,感覺不合理,又想了超級麻煩的辦法可以upate之前先查出原來的資料然後沒有改變的再一一set進去,博主是年輕的賴人,這種方法不頭疼呢!!!今天看了看原先框架裡以前大神們寫的程式碼,原來是這樣處理:

使用的是spring mvc 的@ModelAttribute的特性,@ModelAttribute具體的特性可以參考這位大神寫的

@ModelAttribute特性。@ModelAttribute 會在你請求的方法前去使用




在這裡使用了@ModelAttribute去查詢了一下member資訊,這樣member中沒有在表單中的資料就加載出來了


因為都是member物件,所以利用了@ModelAttribute的特性,如果提交的request中的引數中,有就set進去到member物件中,沒有就不會set,這樣member物件原來的引數就不會丟失,更改的引數也會儲存進去,再呼叫jpa的save方法就沒有問題了。

好了接下來解決manyToOne級聯update的問題:


這裡我的member物件與user物件是一個manyToOne的關係,如果在表單中更改這個one物件時會出現

這個問題是因為什麼呢?我深入的研究了一下,原來是這樣:

當我查詢出這個member物件時,會連帶著也查詢出user物件

這裡觀察下user物件的hash值與id

當我在表單頁面更改這個User物件時,檢視提交上來的member物件時會發現:user的引用沒有改變,只是我更改的id變化了,於是就會報出identifier of an instance of  34 to 31的問題,這個根本原因就是因為load快取的問題,因為表單form只是改變了id值,但是Jpa儲存的時候還是用的原來的user物件引用,所以就會出問題,其實解決這個問題也是十分簡單的,只要重新一個user物件就可以,在這裡也是十分巧妙的解決這個問題,就是在@ModelAttribute的方法中將member物件中的user屬性置為null,這樣就解決了問題


這個問題困擾了好幾天,查網上的資料解決的都不是很清晰,這裡分享出來。